ACIS Tools¶
The ezdxf.acis
sub-package provides some ACIS data management
tools. The main goals of this tools are:
It is NOT a goal to load and edit arbitrary existing ACIS structures.
Don’t even try it!
These tools cannot replace the official ACIS SDK due to the complexity of the data structures and the absence of an ACIS kernel. Without access to the full documentation it is very cumbersome to reverse-engineer entities and their properties, therefore the analysis of the ACIS data structures is limited to the use as embedded data in DXF and DWG files.
The ezdxf library does not provide an ACIS kernel and there are no plans for implementing one because this is far beyond my capabilities, but it is possible to extract geometries made up only by flat polygonal faces (polyhedron) from ACIS data. Exporting polyhedrons as ACIS data and loading this DXF file by Autodesk products or BricsCAD works for SAT data for DXF R2000-R2010 and for SAB data for DXF R2013-R2018.
Important
Always import from the public interface module ezdxf.acis.api
,
the internal package and module structure may change in the future and
imports from other modules than api
will break.
Functions¶
- ezdxf.acis.api.load_dxf(entity: DXFEntity) list[Body] ¶
Load the ACIS bodies from the given DXF entity. This is the recommended way to load ACIS data.
The DXF entity has to be an ACIS based entity and inherit from
ezdxf.entities.Body
. The entity has to be bound to a valid DXF document and the DXF version of the document has to be DXF R2000 or newer.- Raises:
DXFTypeError – invalid DXF entity type
DXFValueError – invalid DXF document
DXFVersionError – invalid DXF version
Warning
Only a limited count of ACIS entities is supported, all unsupported entities are loaded as
NONE_ENTITY
and their data is lost. Exporting suchNONE_ENTITIES
will raise anExportError
exception.To emphasize that again: It is not possible to load and re-export arbitrary ACIS data!
Example:
import ezdxf
from ezdxf.acis import api as acis
doc = ezdxf.readfile("your.dxf")
msp = doc.modelspace()
for e in msp.query("3DSOLID"):
bodies = acis.load_dxf(e)
...
- ezdxf.acis.api.export_dxf(entity: DXFEntity, bodies: Sequence[Body])¶
Store the ACIS bodies in the given DXF entity. This is the recommended way to set ACIS data of DXF entities.
The DXF entity has to be an ACIS based entity and inherit from
ezdxf.entities.Body
. The entity has to be bound to a valid DXF document and the DXF version of the document has to be DXF R2000 or newer.- Raises:
DXFTypeError – invalid DXF entity type
DXFValueError – invalid DXF document
DXFVersionError – invalid DXF version
Example:
import ezdxf
from ezdxf.render import forms
from ezdxf.acis import api as acis
doc = ezdxf.new("R2000")
msp = doc.modelspace()
# create an ACIS body from a simple cube-mesh
body = acis.body_from_mesh(forms.cube())
solid3d = msp.add_3dsolid()
acis.export_dxf(solid3d, [body])
doc.saveas("cube.dxf")
- ezdxf.acis.api.load(data: str | Sequence[str] | bytes | bytearray) list[Body] ¶
Returns a list of
Body
entities from SAT or SAB data. Accepts SAT data as a single string or a sequence of strings and SAB data as bytes or bytearray.
- ezdxf.acis.api.export_sat(bodies: Sequence[Body], version: int = const.DEFAULT_SAT_VERSION) list[str] ¶
Export one or more
Body
entities as text based SAT data.ACIS version 700 is sufficient for DXF versions R2000, R2004, R2007 and R2010, later DXF versions require SAB data.
- Raises:
ExportError – ACIS structures contain unsupported entities
InvalidLinkStructure – corrupt link structure
- ezdxf.acis.api.export_sab(bodies: Sequence[Body], version: int = const.DEFAULT_SAB_VERSION) bytes ¶
Export one or more
Body
entities as binary encoded SAB data.ACIS version 21800 is sufficient for DXF versions R2013 and R2018, earlier DXF versions require SAT data.
- Raises:
ExportError – ACIS structures contain unsupported entities
InvalidLinkStructure – corrupt link structure
- ezdxf.acis.api.mesh_from_body(body: Body, merge_lumps=True) list[MeshTransformer] ¶
Returns a list of
MeshTransformer
instances from the given ACISBody
entity. The list contains multiple meshes if merge_lumps isFalse
or just a single mesh if merge_lumps isTrue
.The ACIS format stores the faces in counter-clockwise orientation where the face-normal points outwards (away) from the solid body (material).
Note
This function returns meshes build up only from flat polygonal
Face
entities, for a tessellation of more complex ACIS entities (spline surfaces, tori, cones, …) is an ACIS kernel required which ezdxf does not provide.- Parameters:
body – ACIS entity of type
Body
merge_lumps – returns all
Lump
entities from a body as a single mesh ifTrue
otherwise eachLump
entity is a separated mesh
- Raises:
TypeError – given body entity has invalid type
The following images show the limitations of the mesh_from_body()
function. The first image shows the source 3DSOLID
entities with
subtraction of entities with flat and curved faces:
Example script to extracts all flat polygonal faces as meshes:
import ezdxf
from ezdxf.acis import api as acis
doc = ezdxf.readfile("3dsolids.dxf")
msp = doc.modelspace()
doc_out = ezdxf.new()
msp_out = doc_out.modelspace()
for e in msp.query("3DSOLID"):
for body in acis.load_dxf(data):
for mesh in acis.mesh_from_body(body):
mesh.render_mesh(msp_out)
doc_out.saveas("meshes.dxf")
The second image shows the flat faces extracted from the 3DSOLID
entities
and exported as Mesh
entities:
As you can see all faces which do not have straight lines as boundaries are lost.
- ezdxf.acis.api.body_from_mesh(mesh: MeshBuilder, precision: int = 6) Body ¶
Returns a ACIS
Body
entity from aMeshBuilder
instance.This entity can be assigned to a
Solid3d
DXF entity as SAT or SAB data according to the version your DXF document uses (SAT for DXF R2000 to R2010 and SAB for DXF R2013 and later).If the mesh contains multiple separated meshes, each mesh will be a separated
Lump
node. If each mesh should get its ownBody
entity, separate the meshes beforehand by the methodseparate_meshes()
.A closed mesh creates a solid body and an open mesh creates an open (hollow) shell. The detection if the mesh is open or closed is based on the edges of the mesh: if all edges of mesh have two adjacent faces the mesh is closed.
The current implementation applies automatically a vertex optimization, which merges coincident vertices into a single vertex.
- ezdxf.acis.api.vertices_from_body(body: Body) list[Vec3] ¶
Returns all stored vertices in the given
Body
entity. The result is not optimized, meaning the vertices are in no particular order and there are duplicates.This function can be useful to determining the approximate bounding box of an ACIS entity. The result is exact for polyhedra with flat faces with straight edges, but not for bodies with curved edges and faces.
- Parameters:
body – ACIS entity of type
Body
- Raises:
TypeError – given body entity has invalid type
Exceptions¶
- class ezdxf.acis.api.AcisException¶
Base exception of the
ezdxf.acis
package.
- class ezdxf.acis.api.ParsingError¶
Exception raised when loading invalid or unknown ACIS structures.
- class ezdxf.acis.api.ExportError¶
Exception raised when exporting invalid or unknown ACIS structures.
- class ezdxf.acis.api.InvalidLinkStructure¶
Exception raised when the internal link structure is damaged.
Entities¶
A document (sat.pdf) about the basic ACIS 7.0 file format is floating in the internet.
This section contains the additional information about the entities, I got from analyzing the SAT data extracted from DXF files exported by BricsCAD.
This documentation ignores the differences to the ACIS format prior to version 7.0 and all this differences are handled internally.
Writing support for ACIS version < 7.0 is not required because all CAD applications should be able to process version 7.0, even if embedded in a very old DXF R2000 format (tested with Autodesk TrueView, BricsCAD and Nemetschek Allplan).
The first goal is to document the entities which are required to represent
a geometry as flat polygonal faces (polyhedron), which can be converted into
a MeshBuilder
object.
Topology Entities:
Geometry Entities:
- ezdxf.acis.entities.NONE_REF¶
Special sentinel entity which supports the
type
attribute and theis_none
property. Represents all unset entities. Use this idiom on any entity type to check if an entity is unset:if entity.is_none: ...
AcisEntity¶
Transform¶
- class ezdxf.acis.entities.Transform(AcisEntity)¶
Represents an affine transformation operation which transform the
body
to the final location, size and rotation.- matrix¶
Transformation matrix of type
ezdxf.math.Matrix44
.
Body¶
Pattern¶
- class ezdxf.acis.entities.Pattern(AcisEntity)¶
Not implemented.
Lump¶
- class ezdxf.acis.entities.Lump(AcisEntity)¶
The lump represents a connected entity and there can be multiple lumps in a
Body
. Multiple lumps are linked together by thenext_lump
attribute which points to the next lump entity the last lump has aNONE_REF
as next lump. Thebody
attribute references to the parentBody
entity.
Wire¶
- class ezdxf.acis.entities.Wire(AcisEntity)¶
Not implemented.
Shell¶
Subshell¶
- class ezdxf.acis.entities.Subshell(AcisEntity)¶
Not implemented.
Face¶
- class ezdxf.acis.entities.Face(AcisEntity)¶
A face is the building block for
Shell
entities. The boundary of a face is represented by one or moreLoop
entities. The spatial geometry of the face is defined by thesurface
object, which is a bounded or unbounded parametric 3d surface (plane, ellipsoid, spline-surface, …).- sense¶
Boolean value of direction of the face normal with respect to the
Surface
entity:True
: “reversed” direction of the face normalFalse
: “forward” for same direction of the face normal
- double_sided¶
Boolean value which indicates the sides of the face:
True
: the face is part of a hollow object and has two sides.False
: the face is part of a solid object and has only one side which points away from the “material”.
- containment¶
Unknown meaning.
If
double_sided
isTrue
:True
is “in”False
is “out”
Loop¶
- class ezdxf.acis.entities.Loop(AcisEntity)¶
A loop represents connected coedges which are building the boundaries of a
Face
, there can be multiple loops for a single face e.g. faces can contain holes. Thecoedge
attribute references the firstCoedge
of the loop, the additional coedges are linked to this firstCoedge
. In closed loops the coedges are organized as a circular list, in open loops the last coedge references theNONE_REF
entity asnext_coedge
and the first coedge references theNONE_REF
asprev_coedge
.
Coedge¶
- class ezdxf.acis.entities.Coedge(AcisEntity)¶
The coedges are a double linked list where
next_coedge
points to the nextCoedge
andprev_coedge
to the previousCoedge
.The
partner_coedge
attribute references the first partnerCoedge
of an adjacentFace
, the partner edges are organized as a circular list. In a manifold closed surface eachFace
is connected to one partner face by anCoedge
. In a non-manifold surface a face can have more than one partner face.- next_coedge¶
References the next
Coedge
, reference theNONE_REF
if it is the last coedge in an openLoop
.
- prev_coedge¶
References the previous
Coedge
, reference theNONE_REF
if it is the first coedge in an openLoop
.
Edge¶
- class ezdxf.acis.entities.Edge(AcisEntity)¶
The
Edge
entity represents the physical edge of an object. Its geometry is defined by the bounded portion of a parametric space curve. This bounds are stored as object-spaceVertex
entities.- start_vertex¶
The start
Vertex
of the space-curve in object coordinates, ifNONE_REF
the curve is unbounded in this direction.
- start_param¶
The parametric starting bound for the parametric curve. Evaluating the
curve
for this parameter should return the coordinates of thestart_vertex
.
- end_vertex¶
The end
Vertex
of the space-curve in object coordinates, ifNONE_REF
the curve is unbounded in this direction.
- end_param¶
The parametric end bound for the parametric curve.
- curve¶
The parametric space-curve which defines this edge. The curve can be the
NULL_REF
while bothVertex
entities are the same vertex. In this case theEdge
represents an single point like the apex of a cone.
- sense¶
Boolean value which indicates the direction of the edge:
True
: the edge has the “reversed” direction as the underlying curveFalse
: the edge has the same direction as the underlying curve (“forward”)
- convexity¶
Unknown meaning, always the string “unknown”.
Vertex¶
Surface¶
- class ezdxf.acis.entities.Surface(AcisEntity)¶
Abstract base class for all parametric surfaces.
The parameterization of any
Surface
maps a 2D rectangle (u, v parameters) into the spatial object-space (x, y, z).- u_bounds¶
Tuple of (start bound, end bound) parameters as two floats which define the bounds of the parametric surface in the u-direction, one or both values can be
math.inf
which indicates an unbounded state of the surface in that direction.
- v_bounds¶
Tuple of (start bound, end bound) parameters as two floats which define the bounds of the parametric surface in the v-direction, one or both values can be
math.inf
which indicates an unbounded state of the surface in that direction.
Plane¶
Curve¶
- class ezdxf.acis.entities.Curve(AcisEntity)¶
Abstract base class for all parametric curves.
The parameterization of any
Curve
maps a 1D line (the parameter) into the spatial object-space (x, y, z).- bounds¶
Tuple of (start bound, end bound) parameters as two floats which define the bounds of the parametric curve, one or both values can be
math.inf
which indicates an unbounded state of the curve in that direction.
StraightCurve¶
PCurve¶
- class ezdxf.acis.entities.PCurve(AcisEntity)¶
Not implemented.