Tutulisper 发表于 2020-2-26 11:01:16

在ucs中如何获取块引用的几何范围

**** Hidden Message *****

gile 发表于 2020-2-26 13:15:29

嗨,
几何扩展总是关于WCS的
如果需要当前UCS的范围,则必须将块参照从UCS转换为WCS,获取范围并将块参照及其范围转换回UCS

公共静态void GetExtentsAboutUcs()
{
var doc=Application.DocumentManager.MdiActiveDocument
var db=doc.Database
var-ed=doc.Editor
var-peo=new-prompentityoptions(“\n选择块引用:”)
peo。SetRejectMessage(“\n所选对象不是块引用”)
peo。AddAllowedClass(typeof(BlockReference),true)
var per=ed.GetEntity(peo)
如果(per.Status!=PromptStatus.OK)
返回
var ucs=ed.CurrentUserCoordinateSystem
使用(var tr=db.TransactionManager.StartTransaction())
{
var br=(BlockReference)tr.GetObject(per.ObjectId,OpenMode.ForWrite)
br.TransformBy(ucs.Inverse())
var exts=br.geometrycextents
使用(var pline=new Polyline())
{
pline。AddVertexAt(0,新点2d(exts.MinPoint.X,exts.MinPoint.Y),0.0,0.0和0.0)
pline。AddVertexAt(1,新点2d(exts.MaxPoint.X,exts.MinPoint.Y),0.0,0.0和0.0)
pline。AddVertexAt(2,新点2d(exts.MaxPoint.X,exts.MaxPoint.Y),0.0,0.0和0.0)
pline。AddVertexAt(3,新点2d(exts.MinPoint.X,exts.MaxPoint.Y),0.0,0.0和0.0)
pline。闭合=真
pline.SetDatabaseDefaults()
var btr=(BlockTableRecord)tr.GetObject(db.CurrentSpaceId,OpenMode.ForWrite)
btr.AppendEntity(pline)
tr.addNewlyCreatedBobObject(pline,true)
pline.TransformBy(ucs)
}
br.TransformBy(ucs)
tr.Commit()
}
}

Tutulisper 发表于 2020-2-26 22:03:50

谢谢,如果我想在BlockReference中获得“折线”或“线”,我如何变换坐标系

公共静态结果缓冲Blkbox(结果缓冲rb)
{
文档curDoc=Application.DocumentManager.MdiActiveDocument
数据库db=HostApplicationServices.WorkingDatabase
编辑器ed=Application.DocumentManager.MdiActiveDocument.Editor
如果(rb==null)返回null
TypedValue[]tvValues=rb.AsArray()
使用(Transaction trans=db.TransactionManager.StartTransaction())
{
ResultBuffer结果=新结果Buffer()
BlockTable bt=(BlockTable)trans.GetObject(db.BlockTableId,OpenMode.ForRead)
实体ent=(实体)trans.GetObject((ObjectId)tvValues。值OpenMode.ForRead)
如果(ent!=null&&ent.GetType()==typeof(BlockReference))
{
BlockReference br=(blockreforence)trans.GetObject((ObjectId)tvValues。值OpenMode.ForRead)
字符串blkname=br.Name
ed。写消息(“\n块名称:(“+blkname+”)
ObjectId blockRecordId=bt
BlockTableRecord:blockRecord=(blocktablerrecord)blockRecordId.GetObject(OpenMode.ForRead)
Extents3d:tmpExtents3D=新的Extents3d()
int-num=0
foreach(blockRecord中的ObjectId entID)
{
实体实体=(实体)trans。GetObject(entID,OpenMode.ForRead)
//字符串str=entity.GetType().Name
//获取“折线”或“线”
if(entity.GetType()。Name==“Polyline”

gile 发表于 2020-2-27 02:17:32

entity.GetType()。名称=“行”)
{
Extents3d:tmp=entity.geometrycextents
tmpExtents3D.加法器(tmp)
num=num+1
}
}
如果(num>0)
{
Point3d-maxpt=tmpExtents3D.MaxPoint
Point3d minpt=tmpExtents3D.MinPoint
//将OCS转换为WCS
矩阵3d mt=br.BlockTransform
Point3d ptmax=maxpt.TransformBy(mt)
Point3d-ptmin=minpt.TransformBy(mt)
结果。将(new-TypedValue((int)添加到LispDataType。点3d、ptmax))
结果。将(new-TypedValue((int)添加到LispDataType。点3d、ptmin))
}
其他
{
返回null
}
}
trans.Commit()
返回结果
}
}

Tutulisper 发表于 2020-2-27 03:04:23

我不确定是否理解您尝试实现的目标,但这里有一个获取块参照中包含的直线和多段线的UCS范围的UCS坐标的示例。   。
公共静态result buffer blk box(result buffer Rb)。
{。
//验证LISP参数。
if (rb == null)返回null;。
TypedValue[] tvValues = rb,as array();。
if (1 。
if (tvValues),TypeCode!= (int)LispDataType,ObjectId)返回null。
ObjectId id =(ObjectId)TV values,价值;。
如果(id,ObjectClass.DxfName!= "INSERT ")返回null。

文档curDoc =应用程序,document manager . MdiActiveDocument;。
数据库db = HostApplicationServices,工作数据库;。
编辑器ed =应用程序,document manager . mdiactivedocument . editor;。
Matrix3d ucs2wcs = ed,CurrentUserCoordinateSystem。
Matrix3d wcs2ucs = ucs2wcs,inverse();。

使用(Transaction trans = db,transaction manager . start transaction())。
{。
result buffer result = new result buffer();。
block reference br =(block reference)transGetObject(id,OpenMode。for read);。
string blkname = br,姓名;。
ed,write message(" \ n块名:("+ blkname +"),);。

使用(DBObjectCollection entity set = new DBObjectCollection())。
{。
brexplode(entity set);。
extents 3d tmpextents 3d = new extents 3d();。
int num = 0;。
foreach(Entity set中的实体实体)。
{。
//获取“折线”或“直线”。
if(实体是折线

Tutulisper 发表于 2020-2-27 03:28:04

实体是直线)。
{。
实体,transform by(wcs 2 UCS);。
tmpExtents3D,AddExtents(实体,几何范围);。
num++;。
}。
实体,dispose();。
}。
if (0 。
{。
结果,add(new typed value((int)lisp data type,Point3d,tmpExtents3D。min point));。
结果,add(new typed value((int)lisp data type,Point3d,tmpExtents3D。MaxPoint));。
}。
}。
运输,commit();。
返回结果;。
}。
}测试结果:(setq bbox (blkbox (car (entsel))))
(command "_.rectang" "_non" (car bbox) "_non" (cadr bbox))但这一切都可以直接用LISP完成,这里有个例子:;; gc:TMatrixFromTo
;; Returns the (4x4) transformation matrix from a coordinate system to another one
;; (same arguments type as 'trans')
;;
;; Arguments
;; from : source coordinate system (integer, vector or ename)
;; to : destination coordinate system (integer, vector or ename)
(defun gc:TMatrixFromTo (from to)
(append
    (mapcar
      (function
      (lambda (v o)
          (append (trans v from to T) (list o))
      )
      )
      '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
      (trans '(0. 0. 0.) to from)
    )
    '((0. 0. 0. 1.))
)
)

;; gc:UcsBoundingBox
;; Returns the UCS coordinates of the entity extents (bounding box)
;; about the current UCS
;;
;; Arguments
;; obj: an entity (ENAME or VLA-OBJCET)
;; _OutputMinPtSym: a quoted symbol (output)
;; _OutputMaxPtSym: a quoted symbol (output)

(defun gc:UcsBoundingBox (obj _OutputMinPtSym _OutputMaxPtSym)
(vl-load-com)
(and (= (type obj) 'ENAME)
       (setq obj (vlax-ename->vla-object obj))
)
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 1 0)))
(vla-GetBoundingBox obj _OutputMinPtSym _OutputMaxPtSym)
(vla-TransformBy obj (vlax-tmatrix (gc:TMatrixFromTo 0 1)))
(set _OutputMinPtSym (vlax-safearray->list (eval _OutputMinPtSym)))
(set _OutputMaxPtSym(vlax-safearray->list (eval _OutputMaxPtSym)))
)使用:(gc:UcsBoundingBox (car (entsel)) 'minPt 'maxPt)
(command "_.rectang" "_non" minPt "_non" maxPt)。

Tutulisper 发表于 2020-2-27 03:34:04

谢谢大家!
您的代码非常好,解决了这个问题
对于某些块引用,它无法获得“GetBoundingBox ”,因此只能进入块引用内部来获得它。
页: [1]
查看完整版本: 在ucs中如何获取块引用的几何范围