Welcome,
Guest
. Please
login
or
register
.
1 Hour
1 Day
1 Week
1 Month
Forever
Login with username, password and session length
News:
Home
Help
Login
Register
TheSwamp
»
Code Red
»
.NET
»
Topic:
in ucs how to get BlockReference's GeometricExtents
« previous
next »
Print
Pages: [
1
] |
Go Down
Author
Topic: in ucs how to get BlockReference's GeometricExtents (Read 2277 times)
0 Members and 1 Guest are viewing this topic.
Tutulisper
Mosquito
Posts: 11
in ucs how to get BlockReference's GeometricExtents
«
on:
February 26, 2020, 11:01:16 AM »
in ucs how to get BlockReference's real GeometricExtents
Logged
gile
Gator
Posts: 2520
Marseille, France
WWW
Re: in ucs how to get BlockReference's GeometricExtents
«
Reply #1 on:
February 26, 2020, 01:15:29 PM »
Hi,
GeometricExtents are always about WCS.
If you want the extents about the current UCS, you have to transform the BlockReference from UCS to WCS, get the extents and transform back the block reference and its extents to UCS.
Code - C#:
[Select]
[
CommandMethod
(
"UCSBBOX"
)
]
public
static
void
GetExtentsAboutUcs
(
)
{
var
doc
=
Application
.
DocumentManager
.
MdiActiveDocument
;
var
db
=
doc
.
Database
;
var
ed
=
doc
.
Editor
;
var
peo
=
new
PromptEntityOptions
(
"
\n
Select block reference: "
)
;
peo
.
SetRejectMessage
(
"
\n
Selected object is not a block reference."
)
;
peo
.
AddAllowedClass
(
typeof
(
BlockReference
)
,
true
)
;
var
per
=
ed
.
GetEntity
(
peo
)
;
if
(
per
.
Status
!=
PromptStatus
.
OK
)
return
;
var
ucs
=
ed
.
CurrentUserCoordinateSystem
;
using
(
var
tr
=
db
.
TransactionManager
.
StartTransaction
(
)
)
{
var
br
=
(
BlockReference
)
tr
.
GetObject
(
per
.
ObjectId
, OpenMode
.
ForWrite
)
;
br
.
TransformBy
(
ucs
.
Inverse
(
)
)
;
var
exts
=
br
.
GeometricExtents
;
using
(
var
pline
=
new
Polyline
(
)
)
{
pline
.
AddVertexAt
(
0
,
new
Point2d
(
exts
.
MinPoint
.
X
, exts
.
MinPoint
.
Y
)
,
0.0
,
0.0
,
0.0
)
;
pline
.
AddVertexAt
(
1
,
new
Point2d
(
exts
.
MaxPoint
.
X
, exts
.
MinPoint
.
Y
)
,
0.0
,
0.0
,
0.0
)
;
pline
.
AddVertexAt
(
2
,
new
Point2d
(
exts
.
MaxPoint
.
X
, exts
.
MaxPoint
.
Y
)
,
0.0
,
0.0
,
0.0
)
;
pline
.
AddVertexAt
(
3
,
new
Point2d
(
exts
.
MinPoint
.
X
, exts
.
MaxPoint
.
Y
)
,
0.0
,
0.0
,
0.0
)
;
pline
.
Closed
=
true
;
pline
.
SetDatabaseDefaults
(
)
;
var
btr
=
(
BlockTableRecord
)
tr
.
GetObject
(
db
.
CurrentSpaceId
, OpenMode
.
ForWrite
)
;
btr
.
AppendEntity
(
pline
)
;
tr
.
AddNewlyCreatedDBObject
(
pline,
true
)
;
pline
.
TransformBy
(
ucs
)
;
}
br
.
TransformBy
(
ucs
)
;
tr
.
Commit
(
)
;
}
}
Logged
Speaking English as a French Frog
Tutulisper
Mosquito
Posts: 11
Re: in ucs how to get BlockReference's GeometricExtents
«
Reply #2 on:
February 26, 2020, 10:03:50 PM »
thanks ,if i want get "Polyline" or "Line" in the BlockReference
how can i transform the Coordinate system。
Code - C#:
[Select]
[
LispFunction
(
"Blkbox"
)
]
public
static
ResultBuffer Blkbox
(
ResultBuffer rb
)
{
Document curDoc
=
Application
.
DocumentManager
.
MdiActiveDocument
;
Database db
=
HostApplicationServices
.
WorkingDatabase
;
Editor ed
=
Application
.
DocumentManager
.
MdiActiveDocument
.
Editor
;
if
(
rb
==
null
)
return
null
;
TypedValue
[
]
tvValues
=
rb
.
AsArray
(
)
;
using
(
Transaction trans
=
db
.
TransactionManager
.
StartTransaction
(
)
)
{
ResultBuffer result
=
new
ResultBuffer
(
)
;
BlockTable bt
=
(
BlockTable
)
trans
.
GetObject
(
db
.
BlockTableId
, OpenMode
.
ForRead
)
;
Entity ent
=
(
Entity
)
trans
.
GetObject
(
(
ObjectId
)
tvValues
[
0
]
.
Value
, OpenMode
.
ForRead
)
;
if
(
ent
!=
null
&&
ent
.
GetType
(
)
==
typeof
(
BlockReference
)
)
{
BlockReference br
=
(
BlockReference
)
trans
.
GetObject
(
(
ObjectId
)
tvValues
[
0
]
.
Value
, OpenMode
.
ForRead
)
;
string
blkname
=
br
.
Name
;
ed
.
WriteMessage
(
"
\n
Block Name: ("
+
blkname
+
")."
)
;
ObjectId blockRecordId
=
bt
[
blkname
]
;
BlockTableRecord blockRecord
=
(
BlockTableRecord
)
blockRecordId
.
GetObject
(
OpenMode
.
ForRead
)
;
Extents3d tmpExtents3D
=
new
Extents3d
(
)
;
int
num
=
0
;
foreach
(
ObjectId entID
in
blockRecord
)
{
Entity entity
=
(
Entity
)
trans
.
GetObject
(
entID, OpenMode
.
ForRead
)
;
// string str = entity.GetType().Name;
// get "Polyline" or "Line"
if
(
entity
.
GetType
(
)
.
Name
==
"Polyline"
||
entity
.
GetType
(
)
.
Name
==
"Line"
)
{
Extents3d tmp
=
entity
.
GeometricExtents
;
tmpExtents3D
.
AddExtents
(
tmp
)
;
num
=
num
+
1
;
}
}
if
(
num
>
0
)
{
Point3d maxpt
=
tmpExtents3D
.
MaxPoint
;
Point3d minpt
=
tmpExtents3D
.
MinPoint
;
// Translate the OCS to WCS
Matrix3d mt
=
br
.
BlockTransform
;
Point3d ptmax
=
maxpt
.
TransformBy
(
mt
)
;
Point3d ptmin
=
minpt
.
TransformBy
(
mt
)
;
result
.
Add
(
new
TypedValue
(
(
int
)
LispDataType
.
Point3d
, ptmax
)
)
;
result
.
Add
(
new
TypedValue
(
(
int
)
LispDataType
.
Point3d
, ptmin
)
)
;
}
else
{
return
null
;
}
}
trans
.
Commit
(
)
;
return
result
;
}
}
«
Last Edit: February 26, 2020, 10:15:22 PM by Tutulisper
»
Logged
gile
Gator
Posts: 2520
Marseille, France
WWW
Re: in ucs how to get BlockReference's GeometricExtents
«
Reply #3 on:
February 27, 2020, 02:17:32 AM »
I'm not sure to understand what you try to achieve but here's an example to get the UCS coordinates of the extents about UCS of lines and polylines contained in the block reference.
Code - C#:
[Select]
[
LispFunction
(
"Blkbox"
)
]
public
static
ResultBuffer Blkbox
(
ResultBuffer rb
)
{
// validation of the LISP argument
if
(
rb
==
null
)
return
null
;
TypedValue
[
]
tvValues
=
rb
.
AsArray
(
)
;
if
(
1
<
tvValues
.
Length
)
return
null
;
if
(
tvValues
[
0
]
.
TypeCode
!=
(
int
)
LispDataType
.
ObjectId
)
return
null
;
ObjectId id
=
(
ObjectId
)
tvValues
[
0
]
.
Value
;
if
(
id
.
ObjectClass
.
DxfName
!=
"INSERT"
)
return
null
;
Document curDoc
=
Application
.
DocumentManager
.
MdiActiveDocument
;
Database db
=
HostApplicationServices
.
WorkingDatabase
;
Editor ed
=
Application
.
DocumentManager
.
MdiActiveDocument
.
Editor
;
Matrix3d ucs2wcs
=
ed
.
CurrentUserCoordinateSystem
;
Matrix3d wcs2ucs
=
ucs2wcs
.
Inverse
(
)
;
using
(
Transaction trans
=
db
.
TransactionManager
.
StartTransaction
(
)
)
{
ResultBuffer result
=
new
ResultBuffer
(
)
;
BlockReference br
=
(
BlockReference
)
trans
.
GetObject
(
id, OpenMode
.
ForRead
)
;
string
blkname
=
br
.
Name
;
ed
.
WriteMessage
(
"
\n
Block Name: ("
+
blkname
+
")."
)
;
using
(
DBObjectCollection entitySet
=
new
DBObjectCollection
(
)
)
{
br
.
Explode
(
entitySet
)
;
Extents3d tmpExtents3D
=
new
Extents3d
(
)
;
int
num
=
0
;
foreach
(
Entity entity
in
entitySet
)
{
// get "Polyline" or "Line"
if
(
entity
is
Polyline
||
entity
is
Line
)
{
entity
.
TransformBy
(
wcs2ucs
)
;
tmpExtents3D
.
AddExtents
(
entity
.
GeometricExtents
)
;
num
++;
}
entity
.
Dispose
(
)
;
}
if
(
0
<
num
)
{
result
.
Add
(
new
TypedValue
(
(
int
)
LispDataType
.
Point3d
, tmpExtents3D
.
MinPoint
)
)
;
result
.
Add
(
new
TypedValue
(
(
int
)
LispDataType
.
Point3d
, tmpExtents3D
.
MaxPoint
)
)
;
}
}
trans
.
Commit
(
)
;
return
result
;
}
}
To test the result:
Code - Auto/Visual Lisp:
[Select]
(
setq
bbox
(
blkbox
(
car
(
entsel
)
)
)
)
(
command
"_.rectang"
"_non"
(
car
bbox
)
"_non"
(
cadr
bbox
)
)
But all this can be done directly with LISP, here's an example:
Code - Auto/Visual Lisp:
[Select]
;; 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
)
)
)
)
using:
Code - Auto/Visual Lisp:
[Select]
(
gc
:UcsBoundingBox
(
car
(
entsel
)
)
'minPt 'maxPt
)
(
command
"_.rectang"
"_non"
minPt
"_non"
maxPt
)
Logged
Speaking English as a French Frog
Tutulisper
Mosquito
Posts: 11
Re: in ucs how to get BlockReference's GeometricExtents
«
Reply #4 on:
February 27, 2020, 03:04:23 AM »
thank you!
your code is very nice and Solved the problem
for some BlockReference it can not get the "GetBoundingBox" so it's only to go inside the BlockReference to get it.
«
Last Edit: February 27, 2020, 11:38:10 AM by Tutulisper
»
Logged
Print
Pages: [
1
] |
Go Up
« previous
next »
TheSwamp
»
Code Red
»
.NET
»
Topic:
in ucs how to get BlockReference's GeometricExtents