diff --git a/Acis.py b/Acis.py index c17c7a7..927b10f 100644 --- a/Acis.py +++ b/Acis.py @@ -1,26 +1,28 @@ # -*- coding: utf-8 -*- +from __future__ import unicode_literals + +__author__ = 'Jens M. Plonka' +__copyright__ = 'Copyright 2023, Germany' +__url__ = "https://www.github.com/jmplonka/InventorLoader" + ''' Acis.py: Collection of classes necessary to read and analyse Standard ACIS Text (*.sat) files. ''' -from __future__ import unicode_literals - -import traceback, Part, Draft, os, FreeCAD, re +import traceback, Part, FreeCAD, re -from importerUtils import * -from FreeCAD import Vector as VEC, Rotation as ROT, Placement as PLC, Matrix as MAT, Base -from math import pi, fabs, degrees, asin, sin, cos, tan, atan2, ceil, e, cosh, sinh, tanh, acos, acosh, asin, asinh, atan, atanh, log, sqrt, exp, log10 -from importerConstants import MIN_0, MIN_PI, MIN_PI2, MIN_INF, MAX_2PI, MAX_PI, MAX_PI2, MAX_INF, MAX_LEN -from importerConstants import CENTER, DIR_X, DIR_Y, DIR_Z, ENCODING_FS - -__author__ = 'Jens M. Plonka' -__copyright__ = 'Copyright 2018, Germany' -__url__ = "https://www.github.com/jmplonka/InventorLoader" +from importerUtils import * +from FreeCAD import Vector as VEC, Placement as PLC, Matrix as MAT, Base +from math import pi, fabs, degrees, asin, sin, cos, tan, atan2, ceil, e, cosh, sinh, tanh, acos, acosh, asin, asinh, atan, atanh, log, sqrt, exp, log10 +from importerConstants import MIN_0, MIN_PI, MIN_PI2, MIN_INF, MAX_2PI, MAX_PI, MAX_PI2, MAX_INF, MAX_LEN, CENTER, DIR_X, DIR_Y, DIR_Z, ENCODING_FS V2D = Base.Vector2d +if (sys.version_info.major > 2): + long = int + # Primitives for Binary File Format (.sab) TAG_CHAR = 2 # 0x02 -> character (unsigned 8 bit) TAG_SHORT = 3 # 0x03 -> 16Bit signed value @@ -46,36 +48,36 @@ TAG_INT64 = 23 # 0x17 -> used by AutoCAD ASM int64 attributes # TAG_FALSE, TAG_TRUE value mappings -def _build_bool_enum_(false_value, true_value, true_key = 'T'): +def __build_bool_enum__(false_value, true_value, true_key = 'T'): return { TAG_TRUE: true_value, true_key: true_value, 1: true_value, TAG_FALSE: false_value, 'F': false_value, 0: false_value, } -RANGE = _build_bool_enum_('I', 'F', 'I') -REFLECTION = _build_bool_enum_('no_reflect', 'reflect') -SURF_RIGID = _build_bool_enum_('non_rigid', 'rigid') -SURF_AXIS_SWEEP = _build_bool_enum_('non_axis_sweep', 'axis_sweep') -ROTATION = _build_bool_enum_('no_rotate', 'rotate') -SHEAR = _build_bool_enum_('no_shear', 'shear') -SENSE = _build_bool_enum_('forward', 'reversed') -SENSEV = _build_bool_enum_('forward_v', 'reverse_v') -SIDES = _build_bool_enum_('single', 'double') -SIDE = _build_bool_enum_('out', 'in') -SURF_BOOL = _build_bool_enum_('FALSE', 'TRUE') -SURF_NORM = _build_bool_enum_('ISO', 'UNKNOWN') -SURF_DIR = _build_bool_enum_('SKIN', 'PERPENDICULAR') -SURF_SWEEP = _build_bool_enum_('angled', 'normal') -CIRC_TYP = _build_bool_enum_('non_cross', 'cross') -CIRC_SMTH = _build_bool_enum_('non_smooth', 'smooth') -CALIBRATED = _build_bool_enum_('uncalibrated', 'calibrated') -CHAMFER_TYPE = _build_bool_enum_('const', 'radius') -CONVEXITY = _build_bool_enum_('concave', 'convex') -RENDER_BLEND = _build_bool_enum_('rb_snapshot', 'rb_envelope') -BOOLEAN = _build_bool_enum_('F', 'T') +RANGE = __build_bool_enum__('I', 'F', 'I') +REFLECTION = __build_bool_enum__('no_reflect', 'reflect') +SURF_RIGID = __build_bool_enum__('non_rigid', 'rigid') +SURF_AXIS_SWEEP = __build_bool_enum__('non_axis_sweep', 'axis_sweep') +ROTATION = __build_bool_enum__('no_rotate', 'rotate') +SHEAR = __build_bool_enum__('no_shear', 'shear') +SENSE = __build_bool_enum__('forward', 'reversed') +SENSEV = __build_bool_enum__('forward_v', 'reverse_v') +SIDES = __build_bool_enum__('single', 'double') +SIDE = __build_bool_enum__('out', 'in') +SURF_BOOL = __build_bool_enum__('FALSE', 'TRUE') +SURF_NORM = __build_bool_enum__('ISO', 'UNKNOWN') +SURF_DIR = __build_bool_enum__('SKIN', 'PERPENDICULAR') +SURF_SWEEP = __build_bool_enum__('angled', 'normal') +CIRC_TYP = __build_bool_enum__('non_cross', 'cross') +CIRC_SMTH = __build_bool_enum__('non_smooth', 'smooth') +CALIBRATED = __build_bool_enum__('uncalibrated', 'calibrated') +CHAMFER_TYPE = __build_bool_enum__('const', 'radius') +CONVEXITY = __build_bool_enum__('concave', 'convex') +RENDER_BLEND = __build_bool_enum__('rb_snapshot', 'rb_envelope') +BOOLEAN = __build_bool_enum__('F', 'T') # TAG_ENUM value mappings -RAD_FORM_ENTS = ['unknown', 'two_ends', 'functional', 'fixed_width'] +RAD_FORM_ENTS = ('unknown', 'two_ends', 'functional', 'fixed_width') VAR_RADIUS = {0: 'single_radius', 1: 'two_radii'} VAR_CHAMFER = {3: 'rounded_chamfer'} @@ -106,10 +108,19 @@ def _build_bool_enum_(false_value, true_value, true_key = 'T'): _getULong = getUInt32 def getReader(): + ''' + Returns the current reader for the ACIS document. + ''' global _reader return _reader def setReader(reader): + ''' + Sets the reader for the current ACIS document. + Parameters: + reader: AcisReader + The current ACIS document's reader + ''' global _reader clearEntities() _reader = reader @@ -155,19 +166,19 @@ def _getStr_SpaceClaim(data, offset, end): _getStr_ = _getStr_DEFAULT -def _set_attribute_DEFAULT(self, entity, pos): +def _set_attribute_DEFAULT(self, record, pos): i = pos - self._next, i = getRefNode(entity, i, 'attrib') - self._previous, i = getRefNode(entity, i, 'attrib') - self._owner, i = getRefNode(entity, i, None) + self._next, i = getRefNode(record, i, 'attrib') + self._previous, i = getRefNode(record, i, 'attrib') + self._owner, i = getRefNode(record, i, None) if ((getVersion() > 15.0) and (isASM() == False)): i += 18 # skip ??? return i -def _set_attribute_SpaceClaim(self, entity, pos): +def _set_attribute_SpaceClaim(self, record, pos): i = pos - self._next, i = getRefNode(entity, i, 'attrib') - self._previous, i = getRefNode(entity, i, 'attrib') - self._owner, i = getRefNode(entity, i, None) + self._next, i = getRefNode(record, i, 'attrib') + self._previous, i = getRefNode(record, i, 'attrib') + self._owner, i = getRefNode(record, i, None) i += 1 # skip ??? return i @@ -258,9 +269,8 @@ class Law(object): # pi= 3.141 def __init__(self, eq): #FIXME: how to handle cross operator??? - self.eq = eq # convert ^ into ** - self.eq = self.eq.replace('^', ' ** ') + self.eq = eq.replace('^', ' ** ') def evaluate(self, X): try: return eval(self.eq) @@ -275,6 +285,9 @@ def init(): _dcIdxAttributes.clear() def clearEntities(): + ''' + Clears all cached enties. + ''' global _nameMtchAttr _nameMtchAttr.clear() @@ -286,8 +299,7 @@ def setVersion(vers): version = vers def getVersion(): - global _reader - return _reader.version + return getReader().version def isASM(): header = getReader().header @@ -301,41 +313,41 @@ def getAsmMajor(): return header.asm[0] return 0 -def createNode(entity): - if (entity is None): return None - if (entity.index < 0): return None - if (entity.node): return entity.node +def createEntity(record): + if (record is None): return None + if (record.index < 0): return None + if (record.entity): return record.entity try: - node = RECORD_2_NODE[entity.name]() + entity = RECORD_2_ENTITY[record.name]() except: #Found unknown class: try to find the base class - types = entity.name.split('-') + types = record.name.split('-') i = 1 - node = Entity() + entity = Entity() t = 'Entity' while (i 2): - return int(val), i return long(val), i def getFloat(chunks, index): @@ -423,7 +433,7 @@ def getText(chunks, index): def getEnumByTag(chunks, index, values): chunk = chunks[index] - if (type(chunk) == AcisChunkUtf8U8): + if (chunk.tag == TAG_UTF8_U8): chunk = AcisChunkEnumValue(TAG_ENUM_VALUE, chunk.val, values) idx = 0 for key in values: @@ -437,7 +447,7 @@ def getEnumByTag(chunks, index, values): break; idx += 1 chunks[index] = chunk - elif (type(chunk) == AcisChunkDouble): + elif (chunk.tag == TAG_DOUBLE): chunk = AcisChunkEnumValue(TAG_ENUM_VALUE, 11 - int(chunk.val), values) chunks[index] = chunk else: @@ -571,27 +581,61 @@ def readKnotsMults(count, chunks, index): mults.append(mult) return knots, mults, i -def adjustMultsKnots(knots, mults, periodic, degree): +def adjustMultsKnots(knots, mults, degree): mults[0] = degree + 1 mults[-1] = degree + 1 -# return knots, mults, False # Force periodic to False!!! - return knots, mults, periodic + return knots, mults -def readPoints2DList(nubs, count, chunks, index): - nubs.uKnots, nubs.uMults, i = readKnotsMults(count, chunks, index) - us = sum(nubs.uMults) - (nubs.uDegree - 1) - nubs.poles = [None for r in range(0, us)] - nubs.weights = [1 for r in range(0, us)] if (nubs.rational) else None +def readPoints2DList(spline, count, chunks, index): + spline.uKnots, spline.uMults, i = readKnotsMults(count, chunks, index) + us = sum(spline.uMults) - (spline.uDegree - 1) + spline.poles = [None for r in range(0, us)] + spline.weights = [1 for r in range(0, us)] if (spline.rational) else None for k in range(0, us): u, i = getLength(chunks, i) v, i = getLength(chunks, i) - nubs.poles[k] = V2D(u, v) - if (nubs.rational): nubs.weights[k], i = getFloat(chunks, i) + spline.poles[k] = V2D(u, v) + if (spline.rational): spline.weights[k], i = getFloat(chunks, i) - nubs.uKnots, nubs.uMults, nubs.uPeriodic = adjustMultsKnots(nubs.uKnots, nubs.uMults, nubs.uPeriodic, nubs.uDegree) + spline.uKnots, spline.uMults = adjustMultsKnots(spline.uKnots, spline.uMults, spline.uDegree) - return i + return spline, i + +def readPoints3DList(spline, count, chunks, index): + spline.uKnots, spline.uMults, i = readKnotsMults(count, chunks, index) + us = sum(spline.uMults) - (spline.uDegree - 1) + spline.poles = [None for r in range(0, us)] + spline.weights = [1 for r in range(0, us)] if (spline.rational) else None + + for u in range(0, us): + spline.poles[u], i = getLocation(chunks, i) + if (spline.rational): spline.weights[u], i = getFloat(chunks, i) + + spline.uKnots, spline.uMults = adjustMultsKnots(spline.uKnots, spline.uMults, spline.uDegree) + + return spline, i + +def readPoints3DSurface(spline, countU, countV, chunks, index): + # row definitions + spline.uKnots, spline.uMults, i = readKnotsMults(countU, chunks, index) + # column definitions + spline.vKnots, spline.vMults, i = readKnotsMults(countV, chunks, i) + + us = sum(spline.uMults) - (spline.uDegree - 1) + vs = sum(spline.vMults) - (spline.vDegree - 1) + + spline.poles = [[None for c in range(0, vs)] for r in range(0, us)] + spline.weights = [[1 for c in range(0, vs)] for r in range(0, us)] if (spline.rational) else None + for v in range(0, vs): + for u in range(0, us): + spline.poles[u][v], i = getLocation(chunks, i) + if (spline.rational): spline.weights[u][v], i = getFloat(chunks, i) + + spline.uKnots, spline.uMults = adjustMultsKnots(spline.uKnots, spline.uMults, spline.uDegree) + spline.vKnots, spline.vMults = adjustMultsKnots(spline.vKnots, spline.vMults, spline.vDegree) + + return spline, i def readBlend(chunks, index): nubs, i = readBS2Curve(chunks, index) @@ -816,7 +860,6 @@ def createBSplinesPCurve(pcurve, surface, sense): surf = surface.build() if (surf is None): return None - number_of_poles = len(pcurve.poles) bsc = Part.Geom2d.BSplineCurve2d() if (pcurve.rational): bsc.buildFromPolesMultsKnots( \ @@ -918,9 +961,8 @@ def readBS2Curve(chunks, index): return None, i if (nbs in ('nubs', 'nurbs')): closure, knots, i = getClosureCurve(chunks, i) - nubs = BS3_Curve(nbs == 'nurbs', closure == 'periodic', dgr) - i = readPoints2DList(nubs, knots, chunks, i) - return nubs, i + spline = BS_Curve(nbs == 'nurbs', closure == 'periodic', dgr) + return readPoints2DList(spline, knots, chunks, i) return None, index def readBS3Curve(chunks, index): @@ -929,9 +971,8 @@ def readBS3Curve(chunks, index): return None, i if (nbs in ('nubs', 'nurbs')): closure, knots, i = getClosureCurve(chunks, i) - spline = BS3_Curve(nbs == 'nurbs', closure == 'periodic', dgr) - i = spline.readPoints3DList(knots, chunks, i) - return spline, i + spline = BS_Curve(nbs == 'nurbs', closure == 'periodic', dgr) + return readPoints3DList(spline, knots, chunks, i) return None, index def readBS3Surface(chunks, index): @@ -940,9 +981,8 @@ def readBS3Surface(chunks, index): return None, i if (nbs in ('nubs', 'nurbs')): closureU, closureV, singularityU, singularityV, countU, countV, i = getClosureSurface(chunks, i) - spline = BS3_Surface(nbs == 'nurbs', closureU == 'periodic', closureV == 'periodic', degreeU, degreeV) - i = spline.readPoints3DMap(countU, countV, chunks, i) - return spline, i + spline = BS_Surface(nbs == 'nurbs', closureU == 'periodic', closureV == 'periodic', degreeU, degreeV) + return readPoints3DSurface(spline, countU, countV, chunks, i) if (nbs == 'summary'): x, i = getFloat(chunks, i) arr, i = getFloatArray(chunks, i) @@ -962,7 +1002,7 @@ def readSplineSurface(chunks, index, tolerance): tol, i = getLength(chunks, i) return spline, tol, i return spline, None, i - if ((singularity == 'none') or (singularity == 4)): + if (singularity in ('none', 4)): rngU, i = getInterval(chunks, i, MIN_INF, MAX_INF, 1.0) rngV, i = getInterval(chunks, i, MIN_INF, MAX_INF, 1.0) clsU, i = getEnumByValue(chunks, i, CLOSURE) @@ -970,7 +1010,7 @@ def readSplineSurface(chunks, index, tolerance): sngU, i = getSingularity(chunks, i) sngV, i = getSingularity(chunks, i) return None, (None, None, rngU, rngV, None, clsU, clsV, sngU, sngV), i - if ((singularity == 'v') or (singularity == 'summary')): + if (singularity in ('v', 'summary')): uKnots, i = getFloatArray(chunks, i) vKnots, i = getFloatArray(chunks, i) tol, i = getLength(chunks, i) @@ -978,14 +1018,16 @@ def readSplineSurface(chunks, index, tolerance): clsV, i = getEnumByValue(chunks, i, CLOSURE) sngU, i = getSingularity(chunks, i) sngV, i = getSingularity(chunks, i) - spline = BS3_Surface(False, (clsU == 'periodic'), (clsV == 'periodic'), 3, 3) + spline = BS_Surface(False, (clsU == 'periodic'), (clsV == 'periodic'), 3, 3) spline.uKnots = uKnots spline.uMults = [3] * len(uKnots) spline.vKnots = vKnots spline.vMults = [3] * len(vKnots) spline.tolerance = tol + spline.uSingularity = sngU + spline.vSingularity = sngV # FIXME: create a surface from these values! -> ../tutorials/2012/Tube and Pipe/Example_iparts/45Elbow.ipt - return None, (uKnots, vKnots, None, None, tol, clsU, clsV, sngU, sngV), i + return spline, None, i raise Exception("Unknown spline singularity '%s'" %(singularity)) def readLofSubdata(chunks, i): @@ -1187,8 +1229,30 @@ def __init__(self): self.n = 0 self.law = 'null_law' self.pcur = None -class BS3_Curve(object): + +class BS_Curve(object): + ''' + B-Spline curve + Attributes: + poles : list + a sequence of points + uMults : list + a list of m + uKnots : list + The knot vector defines where and how the control points affect the NURBS curve. + uPeriodic: bool + True for closed curves, False for open curves + uDegree: int + The number of control points that influence any given point of the curve. + weights: + Each control point can define an individual weight. + rational: bool + False for nubs, True for nurbs + ''' def __init__(self, rational, periodic, degree): + '''Constructor for the B-Spline-Curve + Constructs a new 3D B-Spline curve base on the given parameters + ''' self.poles = [] # sequence of VEC self.uMults = () # tuple of int, e.g. (3, 1, 3) self.uKnots = () # tuple of float, eg. (0, 0.5, 1) @@ -1196,47 +1260,16 @@ def __init__(self, rational, periodic, degree): self.uDegree = degree # int self.weights = [] # sequence of float, e.g. (1, 0.8, 0.2), must have the same length as poles self.rational = rational # boolean: False for nubs, True for nurbs - def readPoints3DList(self, count, chunks, index): - self.uKnots, self.uMults, i = readKnotsMults(count, chunks, index) - us = sum(self.uMults) - (self.uDegree - 1) - self.poles = [None for r in range(0, us)] - self.weights = [1 for r in range(0, us)] if (self.rational) else None - - for u in range(0, us): - self.poles[u], i = getLocation(chunks, i) - if (self.rational): self.weights[u], i = getFloat(chunks, i) - self.uKnots, self.uMults, self.uPeriodic = adjustMultsKnots(self.uKnots, self.uMults, self.uPeriodic, self.uDegree) - return i -class BS3_Surface(BS3_Curve): +class BS_Surface(BS_Curve): def __init__(self, rational, uPeriodic, vPeriodic, uDegree, vDegree): - super(BS3_Surface, self).__init__(rational, uPeriodic, uDegree) + super(BS_Surface, self).__init__(rational, uPeriodic, uDegree) self.poles = [[]] # sequence of sequence ofVEC self.weights = [[]] # sequence of sequence float self.vMults = () # tuple of int, ref. umults self.vKnots = () # tuple of float self.vPeriodic = vPeriodic # boolean self.vDegree = vDegree # int - def readPoints3DMap(self, countU, countV, chunks, index): - # row definitions - self.uKnots, self.uMults, i = readKnotsMults(countU, chunks, index) - # column definitions - self.vKnots, self.vMults, i = readKnotsMults(countV, chunks, i) - - us = sum(self.uMults) - (self.uDegree - 1) - vs = sum(self.vMults) - (self.vDegree - 1) - - self.poles = [[None for c in range(0, vs)] for r in range(0, us)] - self.weights = [[1 for c in range(0, vs)] for r in range(0, us)] if (self.rational) else None - for v in range(0, vs): - for u in range(0, us): - self.poles[u][v], i = getLocation(chunks, i) - if (self.rational): self.weights[u][v], i = getFloat(chunks, i) - - self.uKnots, self.uMults, self.uPeriodic = adjustMultsKnots(self.uKnots, self.uMults, self.uPeriodic, self.uDegree) - self.vKnots, self.vMults, self.vPeriodic = adjustMultsKnots(self.vKnots, self.vMults, self.vPeriodic, self.vDegree) - - return i class Helix(object): def __init__(self): self.radAngles = Interval(Range('I', 1.0), Range('I', 1.0)) @@ -1363,8 +1396,16 @@ def __sub__(self, other): def __add__(self, other): if (isinstance(other, Range)): return self.getLimit() * other.getLimit() return self.getLimit() + other + class Interval(object): def __init__(self, upper, lower): + ''' + Constructor of an interval + lower: Range + The interval's lower range + upper: Range + The interval's upper range + ''' self.lower = upper self.upper = lower def __str__(self): return "%s %s" %(self.lower, self.upper) @@ -1374,6 +1415,7 @@ def getLowerLimit(self): return self.lower.getLimit() def getUpperType(self): return self.upper.type def getUpperLimit(self): return self.upper.getLimit() def getLimit(self): return self.getUpperLimit() - self.getLowerLimit() + class IndexMappings(object): def __init__(self): self.attributes = [] @@ -1391,6 +1433,7 @@ def getEdges(self): return self.__getTypedOwners__('edge') def getFaces(self): return self.__getTypedOwners__('face') + class BeginOfAcisHistoryData(object): pass class Bulletin(object): @@ -1399,10 +1442,10 @@ def __init__(self, old, new): self.new = new def __str__(self): if (self.old.val == -1): - return u"$-1 $%-4d // inserted: %s" %(self.new.val, self.new.entity) + return u"$-1 $%-4d // inserted: %s" %(self.new.val, self.new.record) if (self.new.val == -1): - return u"$%-4d $-1 // deleted: %s" %(self.old.val, self.old.entity) - return u"$%-4d $%-4d // updated id: %s" %(self.old.val, self.new.val, self.new.entity) + return u"$%-4d $-1 // deleted: %s" %(self.old.val, self.old.record) + return u"$%-4d $%-4d // updated id: %s" %(self.old.val, self.new.val, self.new.record) def __repr__(self): return str(self) @@ -1450,10 +1493,10 @@ def __init__(self, history, record): next, i = getInteger(chunks, i + 2) next, i = getInteger(chunks, i) def getRecord(self): return self._record - def getPrevious(self): return self.previous.entity - def getNext(self): return self.next.entity - def getPartner(self): return self.partner.entity - def getMerged(self): return self.merged.entity + def getPrevious(self): return self.previous.record + def getNext(self): return self.next.record + def getPartner(self): return self.partner.record + def getMerged(self): return self.merged.record def resolveLinks(self): self.previous = resolveHistoryLink(self.history, self.previous) self.next = resolveHistoryLink(self.history, self.next) @@ -1467,45 +1510,45 @@ def __repr__(self): class EndOfAcisHistorySection(object): pass class EndOfAcisData(object): pass -# abstract super class +# abstract super class for all entities class Entity(object): def __init__(self): self._attrib = None - self.entity = None + self.record = None self.history = None - self.node = None + self.record = None self.shape = None # FreeCAD shape of the face self.__ready_to_build__ = True # Don't try to create me more than once - def set(self, entity): + def set(self, record): try: - self.entity = entity - entity.node = self - self._attrib, i = getRefNode(entity, 0, None) + self.record = record + record.entity = self + self._attrib, i = getRefNode(record, 0, None) if (getVersion() > 6.0): - self.history, i = getInteger(entity.chunks, i) + self.history, i = getInteger(record.chunks, i) else: self.history = -1 except Exception as e: logError(traceback.format_exc()) return i @property - def index(self): return -1 if (self.entity is None) else self.entity.index - def getType(self): return -1 if (self.entity is None) else self.entity.name + def index(self): return -1 if (self.record is None) else self.record.index + def getType(self): return -1 if (self.record is None) else self.record.name @property - def attrib(self): return None if (self._attrib is None) else self._attrib.node - def __str__(self): return "%s" % (self.entity) - def __repr__(self): return "%r" % (self.entity) + def attrib(self): return None if (self._attrib is None) else self._attrib.entity + def __str__(self): return "%s" % (self.record) + def __repr__(self): return "%r" % (self.record) def getSatText(self): - e = self.entity - sat = e.name - sat += " %r" %(e.chunks[0]) + record = self.record + sat = record.name + sat += " %r" %(record.chunks[0]) if (getVersion() > 6.0): sat += u"%d " %(self.history) sat += self.getSatTextSub(2) else: sat += self.getSatTextSub(1) return sat - def getSatTextSub(self, index): return ''.join("%s" %(c) for c in self.entity.chunks[index:]) + def getSatTextSub(self, index): return ''.join("%s" %(c) for c in self.record.chunks[index:]) def __lt__(self, other): return self.index < other.index def getAttribute(self, clsNames): @@ -1540,46 +1583,40 @@ class T(Entity): def __init__(self): super(T, self).__init__() self.text = '' - def set(self, entity): - self.text, i = getText(entity.chunks, 0) + def set(self, record): + self.text, i = getText(record.chunks, 0) return i class Transform(Entity): def __init__(self): super(Transform, self).__init__() - self.affine = [(1, 0, 0), (0, 1, 0), (0, 0, 1)] - self.transl = (0, 0, 0) - self.scale = 1.0 self.rotation = False self.reflection = False self.shear = False + self.matrix = MAT( + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0) def setBulk(self, chunks, index): - p, i = getPoint(chunks, index) - a11, a21, a31 = p - p, i = getPoint(chunks, i) - a12, a22, a32 = p - p, i = getPoint(chunks, i) - a13, a23, a33 = p - p, i = getLocation(chunks, i) - a14 = p.x - a24 = p.y - a34 = p.z - a44, i = getFloat(chunks, i) + scale = getScale() + a, i = getFloats(chunks, index, 13) + self.matrix = MAT(a[0], a[3], a[6], a[9]*scale, a[1], a[4], a[6], a[10]*scale, a[2], a[5], a[8], a[11]*scale, 0.0, 0.0, 0.0, a[12]) self.rotation, i = getEnumByTag(chunks, i, ROTATION) self.reflection, i = getEnumByTag(chunks, i, REFLECTION) self.shear, i = getEnumByTag(chunks, i, SHEAR) - self.matrix = MAT(a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, 0.0, 0.0, 0.0, a44) return i - def set(self, entity): - i = super(Transform, self).set(entity) - i = self.setBulk(entity.chunks, i) + def set(self, record): + i = super(Transform, self).set(record) + i = self.setBulk(record.chunks, i) return i def getPlacement(self): return PLC(self.matrix) + class Topology(Entity): '''Abstract super class for all topology entities.''' def __init__(self): super(Topology, self).__init__() - def set(self, entity): - i = super(Topology, self).set(entity) + def set(self, record): + i = super(Topology, self).set(record) i = _handle_topology_(self, i) return i class Body(Topology): @@ -1588,14 +1625,14 @@ def __init__(self): self._lump = None # Pointer to LUMP object self._wire = None # Pointer to Wire object self._transform = None # Pointer to Transform object - def set(self, entity): - i = super(Body, self).set(entity) + def set(self, record): + i = super(Body, self).set(record) vrs = getVersion() if (vrs > 27) and (isASM() == False): i += 1 # skip ??? (SpaceClaim) - self._lump, i = getRefNode(entity, i, 'lump') - self._wire, i = getRefNode(entity, i, 'wire') - self._transform, i = getRefNode(entity, i, 'transform') - self.unknown1, i = getUnknownFT(entity.chunks, i) + self._lump, i = getRefNode(record, i, 'lump') + self._wire, i = getRefNode(record, i, 'wire') + self._transform, i = getRefNode(record, i, 'transform') + self.unknown1, i = getUnknownFT(record.chunks, i) return i def getLumps(self): lumps = [] @@ -1611,21 +1648,21 @@ def getWires(self): wires.append(w) w = w.getNext() return wires - def getLump(self): return None if (self._lump is None) else self._lump.node - def getWire(self): return None if (self._wire is None) else self._wire.node - def getTransform(self): return None if (self._transform is None) else self._transform.node + def getLump(self): return None if (self._lump is None) else self._lump.entity + def getWire(self): return None if (self._wire is None) else self._wire.entity + def getTransform(self): return None if (self._transform is None) else self._transform.entity class Lump(Topology): def __init__(self): super(Lump, self).__init__() self._next = None # The next LUMP self._shell = None # The first of shells of the LUMP self._owner = None # The lump's body - def set(self, entity): - i = super(Lump, self).set(entity) - self._next, i = getRefNode(entity, i, 'lump') - self._shell, i = getRefNode(entity, i, 'shell') - self._owner, i = getRefNode(entity, i, 'body') - self.unknown, i = getUnknownFT(entity.chunks, i) + def set(self, record): + i = super(Lump, self).set(record) + self._next, i = getRefNode(record, i, 'lump') + self._shell, i = getRefNode(record, i, 'shell') + self._owner, i = getRefNode(record, i, 'body') + self.unknown, i = getUnknownFT(record.chunks, i) return i def getShells(self): shells = [] @@ -1634,9 +1671,9 @@ def getShells(self): shells.append(s) s = s.getNext() return shells - def getNext(self): return None if (self._next is None) else self._next.node - def getShell(self): return None if (self._shell is None) else self._shell.node - def getOwner(self): return None if (self._owner is None) else self._owner.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getShell(self): return None if (self._shell is None) else self._shell.entity + def getOwner(self): return None if (self._owner is None) else self._owner.entity class Shell(Topology): def __init__(self): super(Shell, self).__init__() @@ -1645,14 +1682,14 @@ def __init__(self): self._face = None # The first of faces of the shell self._wire = None # The shell's wire self._owner = None # The shell's lump - def set(self, entity): - i = super(Shell, self).set(entity) - self._next, i = getRefNode(entity, i, 'shell') - self._shell, i = getRefNode(entity, i, None) - self._face, i = getRefNode(entity, i, 'face') + def set(self, record): + i = super(Shell, self).set(record) + self._next, i = getRefNode(record, i, 'shell') + self._shell, i = getRefNode(record, i, None) + self._face, i = getRefNode(record, i, 'face') if (getVersion() > 1.7): - self._wire, i = getRefNode(entity, i, 'wire') - self._owner, i = getRefNode(entity, i, 'lump') + self._wire, i = getRefNode(record, i, 'wire') + self._owner, i = getRefNode(record, i, 'lump') return i def getFaces(self): faces = [] @@ -1675,11 +1712,11 @@ def getSubShells(self): shells.append(s) s = s.next return shells - def getNext(self): return None if (self._next is None) else self._next.node - def getShell(self): return None if (self._shell is None) else self._shell.node - def getFace(self): return None if (self._face is None) else self._face.node - def getWire(self): return None if (self._wire is None) else self._wire.node - def getLump(self): return None if (self._owner is None) else self._owner.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getShell(self): return None if (self._shell is None) else self._shell.entity + def getFace(self): return None if (self._face is None) else self._face.entity + def getWire(self): return None if (self._wire is None) else self._wire.entity + def getLump(self): return None if (self._owner is None) else self._owner.entity class SubShell(Topology): def __init__(self): super(SubShell, self).__init__() @@ -1688,19 +1725,19 @@ def __init__(self): self._child = None # The child subshell self._face = None # The first face of the subshell self._wire = None # The subshell's wire - def set(self, entity): - i = super(SubShell, self).set(entity) - self._owner = getRefNode(entity, i, 'shell') - self._next = getRefNode(entity, i, None) - self._child = getRefNode(entity, i, None) - self._face = getRefNode(entity, i, 'face') - self._wire = getRefNode(entity, i, 'wire') + def set(self, record): + i = super(SubShell, self).set(record) + self._owner = getRefNode(record, i, 'shell') + self._next = getRefNode(record, i, None) + self._child = getRefNode(record, i, None) + self._face = getRefNode(record, i, 'face') + self._wire = getRefNode(record, i, 'wire') return i - def getOwner(self): return None if (self._owner is None) else self._owner.node - def getNext(self): return None if (self._next is None) else self._next.node - def getChild(self): return None if (self._child is None) else self._child.node - def getFace(self): return None if (self._face is None) else self._face.node - def getWire(self): return None if (self._wire is None) else self._wire.node + def getOwner(self): return None if (self._owner is None) else self._owner.entity + def getNext(self): return None if (self._next is None) else self._next.entity + def getChild(self): return None if (self._child is None) else self._child.entity + def getFace(self): return None if (self._face is None) else self._face.entity + def getWire(self): return None if (self._wire is None) else self._wire.entity class Face(Topology): def __init__(self): super(Face, self).__init__() @@ -1713,17 +1750,17 @@ def __init__(self): self.sides = 'single' # Flag defining face is single or double sided self.side = None # Flag defining face is single or double sided self.containment = False # Flag defining face is containment of double-sided faces - def set(self, entity): - i = super(Face, self).set(entity) - self._next, i = getRefNode(entity, i, 'face') - self._loop, i = getRefNode(entity, i, 'loop') - self._parent, i = getRefNode(entity, i, None) - self.unknown, i = getRefNode(entity, i, None) - self._surface, i = getRefNode(entity, i, 'surface') - self.sense, i = getEnumByTag(entity.chunks, i, SENSE) - self.sides, self.containment, i = getSides(entity.chunks, i) + def set(self, record): + i = super(Face, self).set(record) + self._next, i = getRefNode(record, i, 'face') + self._loop, i = getRefNode(record, i, 'loop') + self._parent, i = getRefNode(record, i, None) + self.unknown, i = getRefNode(record, i, None) + self._surface, i = getRefNode(record, i, 'surface') + self.sense, i = getEnumByTag(record.chunks, i, SENSE) + self.sides, self.containment, i = getSides(record.chunks, i) if ((getVersion() > 9.0) and (isASM() == False)): - self.unknown2, i = getUnknownFT(entity.chunks, i) + self.unknown2, i = getUnknownFT(record.chunks, i) return i def getLoops(self): loops = [] @@ -1732,10 +1769,10 @@ def getLoops(self): loops.append(l) l = l.getNext() return loops - def getNext(self): return None if (self._next is None) else self._next.node - def getLoop(self): return None if (self._loop is None) else self._loop.node - def getParent(self): return None if (self._parent is None) else self._parent.node - def getSurface(self): return None if (self._surface is None) else self._surface.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getLoop(self): return None if (self._loop is None) else self._loop.entity + def getParent(self): return None if (self._parent is None) else self._parent.entity + def getSurface(self): return None if (self._surface is None) else self._surface.entity def buildCoEdges(self): edges = [] loop = self.getLoop() @@ -1765,7 +1802,7 @@ def build(self): # edges can be empty because not all edges can be created right now :( logWarning("Can't apply wires for face %s!" %(surface.Surface)) for f in faces: - Part.show(f, "Face-%d" %(self.entity.index)) + Part.show(f, "Face-%d" %(self.record.index)) else: self.shape = surface return self.shape @@ -1792,17 +1829,17 @@ def __init__(self): self._next = None # The next loop self._coedge = None # The first coedge in the loop self._owner = None # The first coedge in the face - def set(self, entity): - i = super(Loop, self).set(entity) - self._next, i = getRefNode(entity, i, 'loop') - self._coedge, i = getRefNode(entity, i, 'coedge') - self._owner, i = getRefNode(entity, i, 'face') - self.unknown, i = getUnknownFT(entity.chunks, i) + def set(self, record): + i = super(Loop, self).set(record) + self._next, i = getRefNode(record, i, 'loop') + self._coedge, i = getRefNode(record, i, 'coedge') + self._owner, i = getRefNode(record, i, 'face') + self.unknown, i = getUnknownFT(record.chunks, i) if ((getVersion() > 10.0) and (isASM() == False)): i += 1 return i - def getNext(self): return None if (self._next is None) else self._next.node - def getCoEdge(self): return None if (self._coedge is None) else self._coedge.node - def getFace(self): return None if (self._owner is None) else self._owner.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getCoEdge(self): return None if (self._coedge is None) else self._coedge.entity + def getFace(self): return None if (self._owner is None) else self._owner.entity def getCoEdges(self): coedges = [] indexes = [] @@ -1830,18 +1867,18 @@ def __init__(self): self._coedge = None self._owner = None self.side = False - def set(self, entity): - i = super(Wire, self).set(entity) - self._next, i = getRefNode(entity, i, 'wire') - self._coedge, i = getRefNode(entity, i, 'coedge') - self._owner, i = getRefNode(entity, i, None) - self.unknown, i = getRefNode(entity, i, None) - self.side, i = getEnumByTag(entity.chunks, i, SIDE) - self.ft, i = getUnknownFT(entity.chunks, i) + def set(self, record): + i = super(Wire, self).set(record) + self._next, i = getRefNode(record, i, 'wire') + self._coedge, i = getRefNode(record, i, 'coedge') + self._owner, i = getRefNode(record, i, None) + self.unknown, i = getRefNode(record, i, None) + self.side, i = getEnumByTag(record.chunks, i, SIDE) + self.ft, i = getUnknownFT(record.chunks, i) return i - def getNext(self): return None if (self._next is None) else self._next.node - def getCoEdge(self): return None if (self._coedge is None) else self._coedge.node - def getOwner(self): return None if (self._owner is None) else self._owner.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getCoEdge(self): return None if (self._coedge is None) else self._coedge.entity + def getOwner(self): return None if (self._owner is None) else self._owner.entity def getCoEdges(self): coedges = {} ce = self.getCoEdge() @@ -1863,23 +1900,23 @@ def __init__(self): self._owner = None # The coedge's owner self._curve = None self.shape = None - def set(self, entity): - i = super(CoEdge, self).set(entity) - self._next, i = getRefNode(entity, i, 'coedge') - self._previous, i = getRefNode(entity, i, 'coedge') - self._partner, i = getRefNode(entity, i, 'coedge') - self._edge, i = getRefNode(entity, i, 'edge') - self.sense, i = getEnumByTag(entity.chunks, i, SENSE) - self._owner, i = getRefNode(entity, i, None) # can be either Loop or Wire + def set(self, record): + i = super(CoEdge, self).set(record) + self._next, i = getRefNode(record, i, 'coedge') + self._previous, i = getRefNode(record, i, 'coedge') + self._partner, i = getRefNode(record, i, 'coedge') + self._edge, i = getRefNode(record, i, 'edge') + self.sense, i = getEnumByTag(record.chunks, i, SENSE) + self._owner, i = getRefNode(record, i, None) # can be either Loop or Wire if (getAsmMajor() > 217): i += 1 # skip int - self._curve, i = getRefNode(entity, i, 'pcurve') + self._curve, i = getRefNode(record, i, 'pcurve') return i - def getNext(self): return None if (self._next is None) else self._next.node - def getPrevious(self): return None if (self._previous is None) else self._previous.node - def getPartner(self): return None if (self._partner is None) else self._partner.node - def getEdge(self): return None if (self._edge is None) else self._edge.node - def getOwner(self): return None if (self._owner is None) else self._owner.node - def getCurve(self): return None if (self._curve is None) else self._curve.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getPrevious(self): return None if (self._previous is None) else self._previous.entity + def getPartner(self): return None if (self._partner is None) else self._partner.entity + def getEdge(self): return None if (self._edge is None) else self._edge.entity + def getOwner(self): return None if (self._owner is None) else self._owner.entity + def getCurve(self): return None if (self._curve is None) else self._curve.entity def build(self): if (self.__ready_to_build__): self.__ready_to_build__ = False @@ -1894,27 +1931,27 @@ def __init__(self): super(CoEdgeTolerance, self).__init__() self.tStart = 0.0 self.tEnd = 0.0 - def set(self, entity): - i = super(CoEdgeTolerance, self).set(entity) - self.tStart, i = getFloat(entity.chunks, i) - self.tEnd, i = getFloat(entity.chunks, i) - if (entity.chunks[i].tag != TAG_TERMINATOR): + def set(self, record): + i = super(CoEdgeTolerance, self).set(record) + self.tStart, i = getFloat(record.chunks, i) + self.tEnd, i = getFloat(record.chunks, i) + if (record.chunks[i].tag != TAG_TERMINATOR): if (getReader().header.prodVer.startswith('ASM')): asm = getAsmMajor() if (asm > 214): if (asm > 219): - if (entity.chunks[i].tag != TAG_ENTITY_REF): - b, i = getBoolean(entity.chunks, i) - r, i = getRefNode(entity, i, None) # Never seen anything else than '$-1' - while (entity.chunks[i].tag != TAG_TERMINATOR): - if (entity.chunks[i].tag in [TAG_LONG, TAG_FLOAT]): - n, i = getInteger(entity.chunks, i) - if (entity.chunks[i].tag == TAG_TERMINATOR): + if (record.chunks[i].tag != TAG_ENTITY_REF): + b, i = getBoolean(record.chunks, i) + r, i = getRefNode(record, i, None) # Never seen anything else than '$-1' + while (record.chunks[i].tag != TAG_TERMINATOR): + if (record.chunks[i].tag in [TAG_LONG, TAG_FLOAT]): + n, i = getInteger(record.chunks, i) + if (record.chunks[i].tag == TAG_TERMINATOR): break - c, i = readCurve(entity.chunks, i) + c, i = readCurve(record.chunks, i) else: if (getVersion() > 9.0): - b, i = getBoolean(entity.chunks, i) + b, i = getBoolean(record.chunks, i) return i class Edge(Topology): def __init__(self): @@ -1925,34 +1962,34 @@ def __init__(self): self._curve = None # Lying on one the Adjacent faces self.sense = 'forward' self.text = '' - def set(self, entity): - i = super(Edge, self).set(entity) - self._start, i = getRefNode(entity, i, 'vertex') + def set(self, record): + i = super(Edge, self).set(record) + self._start, i = getRefNode(record, i, 'vertex') if (getVersion() > 4.0): - self.parameter1, i = getFloat(entity.chunks, i) + self.parameter1, i = getFloat(record.chunks, i) else: self.parameter1 = 0.0 - self._end, i = getRefNode(entity, i, 'vertex') + self._end, i = getRefNode(record, i, 'vertex') if (getVersion() > 4.0): - self.parameter2, i = getFloat(entity.chunks, i) + self.parameter2, i = getFloat(record.chunks, i) else: self.parameter2 = 1.0 - self._owner, i = getRefNode(entity, i, 'coedge') - self._curve, i = getRefNode(entity, i, 'curve') - self.sense, i = getEnumByTag(entity.chunks, i, SENSE) + self._owner, i = getRefNode(record, i, 'coedge') + self._curve, i = getRefNode(record, i, 'curve') + self.sense, i = getEnumByTag(record.chunks, i, SENSE) if (getVersion() > 5.0): - self.text, i = getText(entity.chunks, i) - self.unknown, i = getUnknownFT(entity.chunks, i) + self.text, i = getText(record.chunks, i) + self.unknown, i = getUnknownFT(record.chunks, i) return i - def getStart(self): return None if (self._start is None) else self._start.node.getPosition() - def getEnd(self): return None if (self._end is None) else self._end.node.getPosition() - def getParent(self): return None if (self._owner is None) else self._owner.node - def getCurve(self): return None if (self._curve is None) else self._curve.node + def getStart(self): return None if (self._start is None) else self._start.entity.getPosition() + def getEnd(self): return None if (self._end is None) else self._end.entity.getPosition() + def getParent(self): return None if (self._owner is None) else self._owner.entity + def getCurve(self): return None if (self._curve is None) else self._curve.entity def getPoints(self): points = [] - ptStart = None if (self._start is None) else self._start.node + ptStart = None if (self._start is None) else self._start.entity if (ptStart is not None): points.append(ptStart.getPosition()) - ptEnd = None if (self._end is None) else self._end.node + ptEnd = None if (self._end is None) else self._end.entity if ((ptEnd is not None) and (ptEnd.index != ptStart.index)): points.append(ptEnd.getPosition()) return points def build(self): @@ -1971,8 +2008,8 @@ class EdgeTolerance(Edge): def __init__(self): super(EdgeTolerance, self).__init__() self.tolerance = 0.0 - def set(self, entity): - i = super(EdgeTolerance, self).set(entity) + def set(self, record): + i = super(EdgeTolerance, self).set(record) return i class Vertex(Topology): def __init__(self): @@ -1980,17 +2017,17 @@ def __init__(self): self._owner = None # One of the vertex' owners self._point = None # The vertex' location self.count = -1 # Number of edges using this vertex - def set(self, entity): - i = super(Vertex, self).set(entity) - self._owner, i = getRefNode(entity, i, 'edge') + def set(self, record): + i = super(Vertex, self).set(record) + self._owner, i = getRefNode(record, i, 'edge') if (getAsmMajor() > 217): i += 1 # inventor-version: 2010 -> workaround - if (entity.chunks[i].tag != 0xC): + if (record.chunks[i].tag != 0xC): i += 1 # number of edges using this vertex - self._point, i = getRefNode(entity, i, 'point') + self._point, i = getRefNode(record, i, 'point') return i - def getParent(self): return None if (self._owner is None) else self._owner.node - def getPoint(self): return None if (self._point is None) else self._point.node + def getParent(self): return None if (self._owner is None) else self._owner.entity + def getPoint(self): return None if (self._point is None) else self._point.entity def getPosition(self): p = self.getPoint() return None if (p is None) else p.position @@ -1998,10 +2035,10 @@ class VertexTolerance(Vertex): def __init__(self): super(VertexTolerance, self).__init__() self.tolerance = 0.0 - def set(self, entity): + def set(self, record): asm_major = getAsmMajor() - i = super(VertexTolerance, self).set(entity) - self.tolerance, i = getFloat(entity.chunks, i) + i = super(VertexTolerance, self).set(record) + self.tolerance, i = getFloat(record.chunks, i) if (asm_major > 217): i += 2 # skip floats return i @@ -2010,20 +2047,20 @@ class Geometry(Entity): def __init__(self, name): super(Geometry, self).__init__() self.__name__ = name - def set(self, entity): - i = super(Geometry, self).set(entity) + def set(self, record): + i = super(Geometry, self).set(record) if ((getVersion() > 10.0) and (isASM() == False)): i += 1 # skip ??? if (getVersion() > 6.0): - anyRef, i = getRefNode(entity, i, None) + anyRef, i = getRefNode(record, i, None) return i def getSatTextSub(self, index): - e = self.entity + record = self.record if (getVersion() > 6.0): - return "%s %s" %(e.chunks[index], self.getSatTextGeometry(index + 1)) + return "%s %s" %(record.chunks[index], self.getSatTextGeometry(index + 1)) return self.getSatTextGeometry(index) - def getSatTextGeometry(self, index): return ''.join("%s" %(c) for c in self.entity.chunks[index:]) + def getSatTextGeometry(self, index): return ''.join("%s" %(c) for c in self.record.chunks[index:]) def __repr__(self): - if (self.entity is None): + if (self.record is None): if (hasattr(self, 'ref')): return "%s { ref %d }" %(self.__name__, self.ref) if (hasattr(self, 'subtype')): @@ -2036,9 +2073,9 @@ def __init__(self, name): self.shape = None def setSubtype(self, chunks, index): return index - def set(self, entity): - i = super(Curve, self).set(entity) - i = self.setSubtype(entity.chunks, i) + def set(self, record): + i = super(Curve, self).set(record) + i = self.setSubtype(record.chunks, i) return i def build(self, start, end): # by default: return a line-segment! logWarning(u" ... '%s' not yet supported - forced to straight-curve!", self.__class__.__name__) @@ -2057,7 +2094,7 @@ class CurveDegenerate(Curve): # degenerate curve "degenerate-curve" def __init__(self): super(CurveDegenerate, self).__init__('degenerate') def getSatTextGeometry(self, index): return u"%s %s" %(self.start, self.range) - def __repr__(self): return u"Curve-Degenerate %s %s #" %s(self.start, self.range) + def __repr__(self): return u"Curve-Degenerate %s %s #" %(self.start, self.range) def setSubtype(self, chunks, index): self.start, i = getLocation(chunks, index) self.range, i = getInterval(chunks, i, MIN_INF, MAX_INF, 1.0) @@ -2111,6 +2148,7 @@ def __init__(self, name = '', subtype = 'cur_int'): self.sense = 'forward' # The IntCurve's reversal flag self.range = Interval(Range('I', MIN_INF), Range('I', MAX_INF)) self.subtype = subtype + self.spline = None self.curve = None def __str__(self): return "%s %s {%s ...}" %(self.__name__, SENSE.get(self.sense, self.sense), self. subtype) def __repr__(self): return "%s %s {%s ...}" %(self.__name__, SENSE.get(self.sense, self.sense), self. subtype) @@ -2125,9 +2163,8 @@ def setProjectionSurface(self, surface, curve): def setCurve(self, chunks, index): self.singularity, i = getSingularity(chunks, index) if (self.singularity == 'full'): - nubs, i = readBS3Curve(chunks, i) + self.spline, i = readBS3Curve(chunks, i) self.tolerance, i = getLength(chunks, i) - self.shape = createBSplinesCurve(nubs, self.sense) elif (self.singularity == 'none'): self.range1, i = getInterval(chunks, i, MIN_INF, MAX_INF, getScale()) val, i= getValue(chunks, i) @@ -2139,9 +2176,9 @@ def setCurve(self, chunks, index): fac, i = getFloat(chunks, i) clsr, i = getEnumByValue(chunks, i, CLOSURE) elif (self.singularity == 'v'): - nubs = BS3_Curve(False, False, 3) - nubs.uKnots, i = getFloatArray(chunks, i) # nubs 3 0 n - nubs.uMults = [3] * len(nubs.uKnots) + self.spline = BS_Curve(False, False, 3) + self.spline.uKnots, i = getFloatArray(chunks, i) # nubs 3 0 n + self.spline.uMults = [3] * len(self.spline.uKnots) self.tolerance, i = getLength(chunks, i) f2, i = getFloat(chunks, i) else: @@ -2515,7 +2552,7 @@ def setSurface(self, chunks, index, inventor): def setRef(self, chunks, index): self.subtype = 'ref' self.ref, i = getInteger(chunks, index) - self.curve = getReader().getSubtypeNode(self.ref) + self.curve = getReader().getSubtypeEntity(self.ref) if (not isinstance(self.curve, Curve)): logError("Expeced CURVE for 'ref %d' but found %s", self.ref, self.curve.__name__) self.curve = None @@ -2527,7 +2564,7 @@ def setBulk(self, chunks, index): try: if ((getVersion() >= 25.0) and (isASM() == False)): id, i = getInteger(chunks, i) # subtype table index - getReader().addSubtypeNode(self) + getReader().addSubtypeEntity(self) prm = CURVE_SET_DATA[self.subtype] fkt = getattr(self, prm[0]) except KeyError as ke: @@ -2542,6 +2579,8 @@ def setSubtype(self, chunks, index): def build(self, start=None, end=None): if (self.__ready_to_build__): self.__ready_to_build__ = False + self.shape = createBSplinesCurve(self.spline, self.sense) + if (self.subtype == 'ref'): cur = self.curve if ((cur is not None) and (not isinstance(cur, Curve))): @@ -2596,7 +2635,7 @@ def setBulk(self, chunks, index): return self.setRef(chunks, i) if ((getVersion() >= 25.0) and (isASM() == False)): id, i = getInteger(chunks, i) # subtype table index - getReader().addSubtypeNode(self) + getReader().addSubtypeEntity(self) if (self.subtype == 'lawintcur'): return self.setLaw(chunks, i, False) if (self.subtype == 'law_int_cur'): return self.setLaw(chunks, i + 1, True) raise Exception("No implementation available for intcurve-intcurve'%s'!" %(self.subtype)) @@ -2630,7 +2669,7 @@ def setImpPar(self, chunks, index): def setRef(self, chunks, index): self.subtype = 'ref' self.ref, i = getInteger(chunks, index) - self.pcurve = getReader().getSubtypeNode(self.ref) + self.pcurve = getReader().getSubtypeEntity(self.ref) if (not isinstance(self.pcurve, CurveP)): logError("Expeced PCURVE for 'ref %d' but found %s", self.ref, self.pcurve.__name__) self.pcurve = None @@ -2642,7 +2681,7 @@ def setBulk(self, chunks, index): try: if ((getVersion() >= 25.0) and (isASM() == False)): id, i = getInteger(chunks, i) # subtype table index - getReader().addSubtypeNode(self) + getReader().addSubtypeEntity(self) prm = PCURVE_SET_DATA[self.subtype] fkt = getattr(self, prm) except KeyError as ke: @@ -2655,15 +2694,15 @@ def setSubtype(self, chunks, index): self.u, i = getFloat(chunks, i + 1) self.v, i = getFloat(chunks, i) return i - def set(self, entity): - i = super(Curve, self).set(entity) - self.type, i = getInteger(entity.chunks, i) + def set(self, record): + i = super(Curve, self).set(record) + self.type, i = getInteger(record.chunks, i) if (self.type == 0): - i = self.setSubtype(entity.chunks, i) + i = self.setSubtype(record.chunks, i) else: - self.pcurve, i = getRefNode(entity, i, 'curve') - self.u, i = getFloat(entity.chunks, i) - self.v, i = getFloat(entity.chunks, i) + self.pcurve, i = getRefNode(record, i, 'curve') + self.u, i = getFloat(record.chunks, i) + self.v, i = getFloat(record.chunks, i) self.subtype = 'ref' return i def build(self, start, end): @@ -2714,9 +2753,9 @@ def getSurface(self): return self def setSubtype(self, chunks, index): return index - def set(self, entity): - i = super(Surface, self).set(entity) - i = self.setSubtype(entity.chunks, i) + def set(self, record): + i = super(Surface, self).set(record) + i = self.setSubtype(record.chunks, i) return i def build(self, face = None): return None class SurfaceCone(Surface): @@ -3709,7 +3748,7 @@ def setSweptTaper(self, chunks, index, inventor): def setRef(self, chunks, index): self.subtype = 'ref' self.ref, i = getInteger(chunks, index) - self.surface = getReader().getSubtypeNode(self.ref) + self.surface = getReader().getSubtypeEntity(self.ref) if (not isinstance(self.surface, Surface)): logError("Expeced SURFACE for 'ref %d' but found %s", self.ref, self.surface.__name__) self.surface = None @@ -3721,7 +3760,7 @@ def setBulk(self, chunks, index): try: if ((getVersion() >= 25.0) and (isASM() == False)): id, i = getInteger(chunks, i) # subtype table index - getReader().addSubtypeNode(self) + getReader().addSubtypeEntity(self) prm = SURFACE_TYPES[self.subtype] fkt = getattr(self, prm[0]) except KeyError as ke: @@ -3729,9 +3768,9 @@ def setBulk(self, chunks, index): return fkt(chunks, i + prm[1], prm[2]) def setSubtype(self, chunks, index): self.sense, i = getEnumByTag(chunks, index, SENSE) - if (self.entity is None): - self.entity = AcisEntity('spline') - self.entity.index = self.index + if (self.record is None): + self.record = Record('spline') + self.record.index = self.index i = self.setBulk(chunks, i + 1) assert (chunks[i].tag == TAG_SUBTYPE_CLOSE), u"-%s %s - pending chunks to read: %s" %(self.index, self.subtype, chunks[i:]) self.rangeU, i = getInterval(chunks, i + 1, MIN_INF, MAX_INF, getScale()) @@ -3887,9 +3926,9 @@ def __init__(self): self.position = CENTER self.count = -1 # Number of references def getSatTextGeometry(self, index): return "%s #" %(vec2sat(self.position)) - def set(self, entity): - i = super(Point, self).set(entity) - self.position, i = getLocation(entity.chunks, i) + def set(self, record): + i = super(Point, self).set(record) + self.position, i = getLocation(record.chunks, i) return i class Refinement(Entity): @@ -3916,9 +3955,9 @@ class AsmHeader(Entity): def __init__(self): super(Entity, self).__init__() self.version = '7.0' - def set(self, entity): - i = super(AsmHeader, self).set(entity) - version, i = getText(entity.chunks, i) + def set(self, record): + i = super(AsmHeader, self).set(record) + version, i = getText(record.chunks, i) v = AsmHeader.getVersion(version) self.major = int(v[0][0]) self.minor = int(v[0][1]) @@ -3933,13 +3972,13 @@ def __init__(self): self._next = None self._previous = None self._owner = None - def set(self, entity): - i = super(Attributes, self).set(entity) - i = _set_attribute_(self, entity, i) + def set(self, record): + i = super(Attributes, self).set(record) + i = _set_attribute_(self, record, i) return i - def getNext(self): return None if (self._next is None) else self._next.node - def getPrevious(self): return None if (self._previous is None) else self._previous.node - def getOwner(self): return None if (self._owner is None) else self._owner.node + def getNext(self): return None if (self._next is None) else self._next.entity + def getPrevious(self): return None if (self._previous is None) else self._previous.entity + def getOwner(self): return None if (self._owner is None) else self._owner.entity class Attrib(Attributes): def __init__(self): super(Attrib, self).__init__() class AttribBt(Attrib): @@ -3952,17 +3991,17 @@ def __init__(self): super(AttribADesk, self).__init__() class AttribADeskColor(AttribADesk): def __init__(self): super(AttribADeskColor, self).__init__() - def set(self, entity): - i = super(AttribADeskColor, self).set(entity) - coloridx, i = getInteger(entity.chunks, i) + def set(self, record): + i = super(AttribADeskColor, self).set(record) + coloridx, i = getInteger(record.chunks, i) return i class AttribADeskMaterial(AttribADesk): def __init__(self): super(AttribADeskMaterial, self).__init__() - def set(self, entity): - i = super(AttribADeskMaterial, self).set(entity) - self.val1, i = getInteger(entity.chunks, i) - self.val2, i = getInteger(entity.chunks, i) + def set(self, record): + i = super(AttribADeskMaterial, self).set(record) + self.val1, i = getInteger(record.chunks, i) + self.val2, i = getInteger(record.chunks, i) return i class AttribADeskTrueColor(AttribADesk): def __init__(self): @@ -3971,9 +4010,9 @@ def __init__(self): self.red = .749 self.green = .749 self.blue = .749 - def set(self, entity): - i = super(AttribADeskTrueColor, self).set(entity) - rgba, i = getInteger(entity.chunks, i) + def set(self, record): + i = super(AttribADeskTrueColor, self).set(record) + rgba, i = getInteger(record.chunks, i) self.alhpa = ((rgba >> 24) & 0xFF) / 255.0 self.red = ((rgba >> 16) & 0xFF) / 255.0 self.green = ((rgba >> 8) & 0xFF) / 255.0 @@ -4018,45 +4057,45 @@ class AttribGenName(AttribGen): def __init__(self): super(AttribGenName, self).__init__() self.text = '' - def set(self, entity): - i = super(AttribGenName, self).set(entity) + def set(self, record): + i = super(AttribGenName, self).set(record) vers = getVersion() if (vers > 1.7): if (vers < 16.0) or (isASM()): i += 4 # [(keep|copy) , (keep_keep), (ignore), (copy)] - self.text, i = getText(entity.chunks, i) + self.text, i = getText(record.chunks, i) return i class AttribGenNameInt32(AttribGenName): def __init__(self): super(AttribGenNameInt32, self).__init__() self.value = 0 - def set(self, entity): - i = super(AttribGenNameInt32, self).set(entity) - self.value, i = getInteger(entity.chunks, i) + def set(self, record): + i = super(AttribGenNameInt32, self).set(record) + self.value, i = getInteger(record.chunks, i) return i class AttribGenNameInt64(AttribGenName): def __init__(self): super(AttribGenNameInt64, self).__init__() self.value = 0 - def set(self, entity): - i = super(AttribGenNameInt64, self).set(entity) - self.value, i = getInteger(entity.chunks, i) + def set(self, record): + i = super(AttribGenNameInt64, self).set(record) + self.value, i = getInteger(record.chunks, i) return i class AttribGenNameString(AttribGenName): def __init__(self): super(AttribGenNameString, self).__init__() self.value = '' - def set(self, entity): - i = super(AttribGenNameString, self).set(entity) - self.value, i = getText(entity.chunks, i) + def set(self, record): + i = super(AttribGenNameString, self).set(record) + self.value, i = getText(record.chunks, i) return i class AttribGenNameReal(AttribGenName): def __init__(self): super(AttribGenNameReal, self).__init__() self.value = '' - def set(self, entity): - i = super(AttribGenNameReal, self).set(entity) - self.value, i = getFloat(entity.chunks, i) + def set(self, record): + i = super(AttribGenNameReal, self).set(record) + self.value, i = getFloat(record.chunks, i) return i class AttribKcId(Attrib): # string with numbers @@ -4097,11 +4136,11 @@ def __init__(self): self.red = 0.749 self.green = 0.749 self.blue = 0.749 - def set(self, entity): - i = super(AttribStRgbColor, self).set(entity) - self.red, i = getFloat(entity.chunks, i) - self.green, i = getFloat(entity.chunks, i) - self.blue, i = getFloat(entity.chunks, i) + def set(self, record): + i = super(AttribStRgbColor, self).set(record) + self.red, i = getFloat(record.chunks, i) + self.green, i = getFloat(record.chunks, i) + self.blue, i = getFloat(record.chunks, i) return i class AttribStDisplay(AttribSt): def __init__(self): super(AttribStDisplay, self).__init__() @@ -4124,8 +4163,8 @@ def __init__(self): super(AttribTsl, self).__init__() class AttribTslColour(AttribTsl): def __init__(self): super(AttribTslColour, self).__init__() - def set(self, entity): - i = super(AttribTslColour, self).set(entity) + def set(self, record): + i = super(AttribTslColour, self).set(record) return i class AttribTslId(AttribTsl): def __init__(self): super(AttribTslId, self).__init__() @@ -4181,17 +4220,17 @@ class AttribMixOrganizationUnfoldInfo(AttribMixOrganization): def __init__(self): super(AttribMixOrganizationUnfoldInfo, self).__init__() class AttribNamingMatching(Attrib): def __init__(self): super(AttribNamingMatching, self).__init__() - def set(self, entity): - i = super(AttribNamingMatching, self).set(entity) + def set(self, record): + i = super(AttribNamingMatching, self).set(record) if (getAsmMajor() > 215): i += 1 # i == 5??? return i class AttribNamingMatchingNMxMatchedEntity(AttribNamingMatching): # [dxIdx, msk] n1, n2 def __init__(self): super(AttribNamingMatchingNMxMatchedEntity, self).__init__() - def set(self, entity): - i = super(AttribNamingMatchingNMxMatchedEntity, self).set(entity) - self.mapping, i = getDcIndexMappings(entity.chunks, i, self) - self.a , i = getIntegers(entity.chunks, i, 2) + def set(self, record): + i = super(AttribNamingMatchingNMxMatchedEntity, self).set(record) + self.mapping, i = getDcIndexMappings(record.chunks, i, self) + self.a , i = getIntegers(record.chunks, i, 2) return i class AttribNamingMatchingNMxEdgeCurve(AttribNamingMatching): def __init__(self): super(AttribNamingMatchingNMxEdgeCurve, self).__init__() @@ -4212,48 +4251,48 @@ def __init__(self): self.idxCreator = -1 self.mapping = [] self.red = self.green = self.blue = 0xBE / 255.0 # light gray - def set(self, entity): - i = super(AttribNamingMatchingNMxFFColorEntity, self).set(entity) - self.a1 , i = getIntegers(entity.chunks, i, 2) - self.name , i = getText(entity.chunks, i) - self.mapping, i = getDcIndexMappings(entity.chunks, i, self) + def set(self, record): + i = super(AttribNamingMatchingNMxFFColorEntity, self).set(record) + self.a1 , i = getIntegers(record.chunks, i, 2) + self.name , i = getText(record.chunks, i) + self.mapping, i = getDcIndexMappings(record.chunks, i, self) return i class AttribNamingMatchingNMxThreadEntity(AttribNamingMatching): # x1, x2, V1, V2, n1, V2, [????] def __init__(self): super(AttribNamingMatchingNMxThreadEntity, self).__init__() - def set(self, entity): - i = super(AttribNamingMatchingNMxThreadEntity, self).set(entity) - self.x , i = getFloat(entity.chunks, i) - self.y , i = getFloat(entity.chunks, i) - self.n1 , i = getInteger(entity.chunks, i) - self.p1 , i = getPoint(entity.chunks, i) - self.p2 , i = getPoint(entity.chunks, i) - self.n2 , i = getInteger(entity.chunks, i) - self.p3 , i = getPoint(entity.chunks, i) - self.n2 , i = getInteger(entity.chunks, i) - self.t1 , i = getText(entity.chunks, i) - self.t2 , i = getText(entity.chunks, i) - self.n3 , i = getInteger(entity.chunks, i) - self.t3 , i = getText(entity.chunks, i) - self.t4 , i = getText(entity.chunks, i) - self.t5 , i = getText(entity.chunks, i) - self.n4 , i = getInteger(entity.chunks, i) - self.t3 , i = getText(entity.chunks, i) + def set(self, record): + i = super(AttribNamingMatchingNMxThreadEntity, self).set(record) + self.x , i = getFloat(record.chunks, i) + self.y , i = getFloat(record.chunks, i) + self.n1 , i = getInteger(record.chunks, i) + self.p1 , i = getPoint(record.chunks, i) + self.p2 , i = getPoint(record.chunks, i) + self.n2 , i = getInteger(record.chunks, i) + self.p3 , i = getPoint(record.chunks, i) + self.n2 , i = getInteger(record.chunks, i) + self.t1 , i = getText(record.chunks, i) + self.t2 , i = getText(record.chunks, i) + self.n3 , i = getInteger(record.chunks, i) + self.t3 , i = getText(record.chunks, i) + self.t4 , i = getText(record.chunks, i) + self.t5 , i = getText(record.chunks, i) + self.n4 , i = getInteger(record.chunks, i) + self.t3 , i = getText(record.chunks, i) self.lst = [] for n in range(self.n2): - t1, i = getText(entity.chunks, i) - t2, i = getText(entity.chunks, i) - t3, i = getText(entity.chunks, i) - t4, i = getText(entity.chunks, i) - t5, i = getText(entity.chunks, i) - t6, i = getText(entity.chunks, i) - t7, i = getText(entity.chunks, i) - t8, i = getText(entity.chunks, i) + t1, i = getText(record.chunks, i) + t2, i = getText(record.chunks, i) + t3, i = getText(record.chunks, i) + t4, i = getText(record.chunks, i) + t5, i = getText(record.chunks, i) + t6, i = getText(record.chunks, i) + t7, i = getText(record.chunks, i) + t8, i = getText(record.chunks, i) self.lst.append((t1, t2, t3, t4, t5, t6, t7, t8)) - self.mapping, i = getDcIndexMappings(entity.chunks, i, self) - self.p4 , i = getPoint(entity.chunks, i) - self.p5 , i = getPoint(entity.chunks, i) - self.n5 , i = getInteger(entity.chunks, i) + self.mapping, i = getDcIndexMappings(record.chunks, i, self) + self.p4 , i = getPoint(record.chunks, i) + self.p5 , i = getPoint(record.chunks, i) + self.n5 , i = getInteger(record.chunks, i) return i class AttribNamingMatchingNMxTagWeldLateralFaceName(AttribNamingMatching): @@ -4271,11 +4310,11 @@ def __init__(self): super(AttribNamingMatchingNMxWireTag, self).__init__() class AttribNamingMatchingNMxFeatureOrientation(AttribNamingMatching): def __init__(self): super(AttribNamingMatchingNMxFeatureOrientation, self).__init__() - def set(self, entity): - i = super(AttribNamingMatchingNMxFeatureOrientation, self).set(entity) - if (entity.chunks[i].tag != TAG_ENTITY_REF): i += 1 - self.ref1, i = getRefNode(entity, i, 'curve') - self.ref2, i = getRefNode(entity, i, 'curve') + def set(self, record): + i = super(AttribNamingMatchingNMxFeatureOrientation, self).set(record) + if (record.chunks[i].tag != TAG_ENTITY_REF): i += 1 + self.ref1, i = getRefNode(record, i, 'curve') + self.ref2, i = getRefNode(record, i, 'curve') return i class AttribNamingMatchingNMxGenTagDisambiguation(AttribNamingMatching): # n1 @@ -4286,9 +4325,9 @@ def __init__(self): super(AttribNamingMatchingNMxFeatureDependency, self).__init class AttribNamingMatchingNMxBrepTag(AttribNamingMatching): def __init__(self): super(AttribNamingMatchingNMxBrepTag, self).__init__() - def set(self, entity): - i = super(AttribNamingMatchingNMxBrepTag, self).set(entity) - self.mapping, i = getDcIndexMappings(entity.chunks, i, self) # (DC-index, mask){n} + def set(self, record): + i = super(AttribNamingMatchingNMxBrepTag, self).set(record) + self.mapping, i = getDcIndexMappings(record.chunks, i, self) # (DC-index, mask){n} return i class AttribNamingMatchingNMxBrepTagFeature(AttribNamingMatchingNMxBrepTag): # no more values @@ -4429,12 +4468,12 @@ def __init__(self): super(AttribNamingMatchingNMxBrepTagNameFoldFace, self).__in class AttribNamingMatchingNMxBrepTagNameGenerated(AttribNamingMatchingNMxBrepTagName): # n1, n2, n3 def __init__(self): super(AttribNamingMatchingNMxBrepTagNameGenerated, self).__init__() - def set(self, entity): + def set(self, record): global _nameMtchAttr - i = super(AttribNamingMatchingNMxBrepTagNameGenerated, self).set(entity) - self.key, i = getInteger(entity.chunks, i) - self.n2, i = getInteger(entity.chunks, i) - self.n3, i = getInteger(entity.chunks, i) + i = super(AttribNamingMatchingNMxBrepTagNameGenerated, self).set(record) + self.key, i = getInteger(record.chunks, i) + self.n2, i = getInteger(record.chunks, i) + self.n3, i = getInteger(record.chunks, i) lst = _nameMtchAttr.get(self.key, None) if (lst is None): lst = [] @@ -4622,7 +4661,7 @@ def __init__(self, tag = TAG_ENUM_VALUE, value = None, values = None): self.values = values def __repr__(self): try: - return u"%s " %(values[self.val]) + return u"%s " %(self.values[self.val]) except: return u"%s " %(self.val) def read(self, data, offset): @@ -4630,14 +4669,14 @@ def read(self, data, offset): self.val, i = _getULong(data, offset) return i def getValue(self): - if (values): + if (self.values): return self.values.item(self.val) return self.val class AcisChunkEntityRef(_AcisChunk_): '''Entity reference''' - def __init__(self, value = -1, entity = None): + def __init__(self, value = -1, record = None): super(AcisChunkEntityRef, self).__init__(TAG_ENTITY_REF, value) - self.entity = entity + self.record = record def __repr__(self): return u"$%s " %(self.val) class AcisChunkIdent(_AcisChunk_): '''name of the base class''' @@ -4666,7 +4705,7 @@ class AcisChunkSubtypeClose(_AcisChunk_): def __init__(self, value = None): super(AcisChunkSubtypeClose, self).__init__(TAG_SUBTYPE_CLOSE, u"}") class AcisChunkTerminator(_AcisChunk_): - '''terminator char ('#') for the entity''' + '''terminator char ('#') for the record''' def __init__(self, value = None): super(AcisChunkTerminator, self).__init__(TAG_TERMINATOR, u"#") def __repr__(self): return u"#" @@ -4715,19 +4754,19 @@ def __init__(self, value = None): } class History(object): - def __init__(self, entity): + def __init__(self, record): super(History, self).__init__() - self._record = entity - entity.index = -1 - self.history_stream , i = getValue(entity.chunks, 0) - self.current_state , i = getInteger(entity.chunks, i) # current delta_state - self.next_state , i = getInteger(entity.chunks, i) # next state to with respect to roll back - self.keep_max_states, i = getInteger(entity.chunks, i) # max number of states to keep - self.unknown , i = getInteger(entity.chunks, i) - self.ds_current , i = getValue(entity.chunks, i) # current delta state, a.k. "working state" - self.ds_root , i = getValue(entity.chunks, i) # root delta state - self.ds_active , i = getValue(entity.chunks, i) # the most recent delta state - self.attribute , i = getValue(entity.chunks, i) # history's attributes. + self._record = record + record.index = -1 + self.history_stream , i = getValue(record.chunks, 0) + self.current_state , i = getInteger(record.chunks, i) # current delta_state + self.next_state , i = getInteger(record.chunks, i) # next state to with respect to roll back + self.keep_max_states, i = getInteger(record.chunks, i) # max number of states to keep + self.unknown , i = getInteger(record.chunks, i) + self.ds_current , i = getValue(record.chunks, i) # current delta state, a.k. "working state" + self.ds_root , i = getValue(record.chunks, i) # root delta state + self.ds_active , i = getValue(record.chunks, i) # the most recent delta state + self.attribute , i = getValue(record.chunks, i) # history's attributes. self.delta_states = [] def getRecord(self): return self._record @@ -4738,7 +4777,7 @@ def resolveDeltaStates(self): for ds in self.delta_states: ds.resolveLinks() def getRoot(self): - return self.ds_root.entity + return self.ds_root.record def __str__(self): return "SAT %s: %d %d %d %d %s %s %s %s" %(self.history_stream, self.current_state, self.next_state, self.keep_max_states, self.unknown, self.ds_current, self.ds_root, self.ds_active, self.attribute) def __repr__(self): @@ -4782,7 +4821,6 @@ def version2int(version): ACIS_REF_NONE = AcisChunkEntityRef(-1) class AcisReader(object): - _getLong = getSInt32 # by default 4Bytes def __init__(self, stream): super(AcisReader, self).__init__() self._stream = stream @@ -4791,16 +4829,16 @@ def __init__(self, stream): self._length = 0 self._refChunks = {-1: ACIS_REF_NONE} self.header = Header() - self._entities = [] + self._records = [] self.history = None self.resolved = False self.bodies = [] self._subtypes = [] - def addSubtypeNode(self, node): - self._subtypes.append(node) + def addSubtypeEntity(self, entity): + self._subtypes.append(entity) - def getSubtypeNode(self, ref): + def getSubtypeEntity(self, ref): return self._subtypes[ref] def _hasNext(self): @@ -4858,6 +4896,14 @@ def _translateChunk(self, token): pass return tag, val + @property + def version(self): + return self.header.version + + @property + def scale(self): + return self.header.scale + def _readChunkText(self): self._skipWhiteSpace() if (self._isSingleChar()): @@ -4892,14 +4938,6 @@ def _readChunkBinary(self): raise Exception("Don't know to read TAG %X" %(tag)) return chunk - @property - def version(self): - return self.header.version - - @property - def scale(self): - return self.header.scale - def _readHeaderText(self): self._pos = 0 data = self._stream.readline() @@ -4947,8 +4985,9 @@ def _readHeaderBinary(self): _getStr_ = _getStr_SpaceClaim _handle_topology_ = _handle_topology_SpaceClaim _set_attribute_ = _set_attribute_SpaceClaim - dummy = self._readChunkBinary() # True | False - dummy = self._readChunkBinary() # e.g. SPT5X6MJB_CC42A7Z4XQU39P3RUX3QNS8TMFV67BA_VJ86VA83VFP7V2DKCQ8NX2CNKF87AKCQ3R + dummy = self._readChunkBinary() # True | False (read next chunk?) + if (dummy.tag == TAG_TRUE): + dummy = self._readChunkBinary() # e.g. SPT5X6MJB_CC42A7Z4XQU39P3RUX3QNS8TMFV67BA_VJ86VA83VFP7V2DKCQ8NX2CNKF87AKCQ3R return True # setVersion(self.version) return False @@ -4961,7 +5000,7 @@ def _readRecordText(self, index): if (name.startswith('-')): id = int(name[1:]) name = self._readChunkText() - record = AcisEntity(name) + record = Record(name) record.index = id while (self._hasNext()): token = self._readChunkText() @@ -4974,7 +5013,7 @@ def _readRecordText(self, index): else: try: chunk = ACIS_VALUE_CHUNKS[tag](val) - except KeyError as ke: + except KeyError: raise Exception("Don't know to read TAG %X" %(tag)) record.chunks.append(chunk) if (chunk.tag == TAG_TERMINATOR): @@ -4993,7 +5032,7 @@ def _readRecordBinary(self, index): chunk = self._readChunkBinary() if (chunk.val == 'ASM'): chunk.val = 'ACIS' names.append(chunk.val) - record = AcisEntity('-'.join(names)) + record = Record('-'.join(names)) record.index = id if (not record.name.startswith('End-of-')): while (self._hasNext()): @@ -5006,17 +5045,17 @@ def _readRecordBinary(self, index): def _resolfChunkReferences(self): for ref in self._refChunks.values(): try: - ref.entity = self._entities[ref.val] + ref.record = self._records[ref.val] except: pass - self._refChunks[-1].entity = None + self._refChunks[-1].record = None return - def getEntity(self, index): - return self._entities[index] + def getRecord(self, index): + return self._records[index] - def getEntities(self): - return self._entities + def getRecords(self): + return self._records def readText(self): setReader(self) @@ -5025,38 +5064,38 @@ def readText(self): self._length = len(self._data) historySec = False index = 0 - entityIdx = 0 + recordIdx = 0 init() record, index = self._readRecordText(index) if (record.name == 'asmheader'): asmheader = AsmHeader() asmheader.set(record) if (record.name != 'T'): - self._entities += [None for _ in range(record.index - len(self._entities) + 1)] - self._entities[record.index] = record + self._records += [None for _ in range(record.index - len(self._records) + 1)] + self._records[record.index] = record while (self._hasNext()): record, index = self._readRecordText(index) if (record): if (record.name == "Begin-of-ACIS-History-Data"): historySec = True - entityIdx = record.index + recordIdx = record.index self.history = History(record) - self.history.index = entityIdx + self.history.index = recordIdx index = 0 elif (record.name == "End-of-ACIS-History-Section"): historySec = False record.index = -1 - index = entityIdx + index = recordIdx elif (record.name == "End-of-ACIS-data"): record.index = -1 - self._entities.append(record) + self._records.append(record) else: if (historySec): ds = DeltaState(self.history, record) self.history.delta_states.append(ds) else: - self._entities += [None for _ in range(record.index - len(self._entities) + 1)] - self._entities[record.index] = record + self._records += [None for _ in range(record.index - len(self._records) + 1)] + self._records[record.index] = record self._resolfChunkReferences() return True @@ -5067,7 +5106,7 @@ def readBinary(self): self._pos = 0 historySec = False index = 0 - entityIdx = 0 + recordIdx = 0 init() self._readHeaderBinary() SPACE_CLAIM.clear() @@ -5076,33 +5115,33 @@ def readBinary(self): record, index = self._readRecordBinary(index) if (record.name == "Begin-of-ACIS-History-Data"): historySec = True - entityIdx = record.index + recordIdx = record.index self.history = History(record) - self.history.index = entityIdx + self.history.index = recordIdx index = 0 elif (record.name == "End-of-ACIS-History-Section"): historySec = False record.index = -1 - index = entityIdx + index = recordIdx elif (record.name == "End-of-ACIS-data"): record.index = -1 - self._entities.append(record) + self._records.append(record) else: if (historySec): ds = DeltaState(self.history, record) self.history.delta_states.append(ds) else: - self._entities.append(record) + self._records.append(record) self._resolfChunkReferences() setReader(self) return True -class AcisEntity(object): +class Record(object): def __init__(self, name): self.chunks = [] self.name = name self.index = -1 - self.node = None + self.entity = None def __repr__(self): return "%s %s" %(self.name, ''.join(c.__repr__() for c in self.chunks)) @@ -5260,7 +5299,7 @@ def __str__(self): "plane": BDY_GEOM_PLANE } -RECORD_2_NODE = { +RECORD_2_ENTITY = { "annotation": Annotation, "primitive_annotation-annotation": AnnotationPrimitive, "split_annotation-annotation": AnnotationSplit, diff --git a/Acis2Step.py b/Acis2Step.py index c370832..8ff1fb8 100644 --- a/Acis2Step.py +++ b/Acis2Step.py @@ -4,13 +4,19 @@ Acis2Step.py: ''' +import traceback, os, sys, math, io +import Part +import Acis + from datetime import datetime from importerUtils import isEqual, getDumpFolder -from FreeCAD import Vector as VEC, Placement as PLC -from importerUtils import logInfo, logWarning, logError, logAlways, isEqual1D, getAuthor, getDescription, getColorDefault -from importerConstants import CENTER, DIR_X, DIR_Y, DIR_Z, ENCODING_FS +from FreeCAD import Vector as VEC, Rotation as ROT, Placement as PLC, Matrix as MAT +from importerUtils import logInfo, logWarning, logError, isEqual1D, getColorDefault, getDumpFolder, getAuthor, getDescription +from importerConstants import CENTER, DIR_X, DIR_Y, DIR_Z, EPS -import traceback, inspect, os, sys, Acis, math, re, Part, io +if (sys.version_info.major > 2): + long = int + unicode = str ############################################################# # private variables @@ -38,6 +44,9 @@ # private functions ############################################################# +def _isIdentity(transf): + return transf.Base.distanceToPoint(CENTER) < EPS and transf.Rotation.Axis.getAngle(DIR_Z) < EPS + def _getE(o): if (isinstance(o, E)): return o if (o is None): return None @@ -90,6 +99,30 @@ def _obj2str(o): def _values3D(v): return [v.x, v.y, v.z] +def rotation_matrix(axis, angle): + axis.normalize() + a = math.cos(angle / 2.0) + aa = a * a + v = axis * math.sin(angle / -2.0) + b = v.x + c = v.y + d = v.z + aa, bb, cc, dd = a * a, b * b, c * c, d * d + bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d + m11 = aa + bb - cc - dd + m12 = 2 * (bc + ad) + m13 = 2 * (bd - ac) + m21 = 2 * (bc - ad) + m22 = aa + cc - bb - dd + m23 = 2 * (cd + ab) + m31 = 2 * (bd + ac) + m32 = 2 * (cd - ab) + m33 = aa + dd - bb - cc + return MAT(m11, m12, m13, 0.0, m21, m22, m23, 0.0, m31, m32, m33, 0.0, 0.0, 0.0, 0.0, 0.0) + +def _rotate(vec, rotation): + return rotation_matrix(rotation.Axis, rotation.Angle) * vec + def getColor(entity): global _colorPalette @@ -127,22 +160,25 @@ def assignColor(color, item, context): _assignments[keyRGB] = assignment style.styles = [assignment] +def _createTransformation(ref1, ref2, idt): + return ListEntity(REPRESENTATION_RELATIONSHIP(None, ref1, ref2), REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(idt), SHAPE_REPRESENTATION_RELATIONSHIP()) + def _createUnit(tolerance): - unit = UNIT() - uncr = GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT() - glob = GLOBAL_UNIT_ASSIGNED_CONTEXT() - repr = REPRESENTATION_CONTEXT() + unit = UNIT() + uncr_ctx = GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT() + glob_ctx = GLOBAL_UNIT_ASSIGNED_CONTEXT() + repr_ctx = REPRESENTATION_CONTEXT() length = ListEntity(LENGTH_UNIT(None), NAMED_UNIT(AnyEntity()), SI_UNIT('MILLI', 'METRE')) angle1 = ListEntity(NAMED_UNIT(AnyEntity()), PLANE_ANGLE_UNIT(None), SI_UNIT(None, 'RADIAN')) angle2 = ListEntity(NAMED_UNIT(AnyEntity()), SI_UNIT(None, 'STERADIAN'), SOLID_ANGLE_UNIT(None)) uncertainty = UNCERTAINTY_MEASURE_WITH_UNIT(tolerance, length) - uncr.units = (uncertainty,) + uncr_ctx.units = (uncertainty,) - glob.assignments = (length, angle1, angle2) + glob_ctx.assignments = (length, angle1, angle2) - unit.entities = _createGeometricRepresentationList(uncr, glob, repr) + unit.entities = _createGeometricRepresentationList(uncr_ctx, glob_ctx, repr_ctx) return unit def _createCartesianPoint(fcVec, name = ''): @@ -212,24 +248,24 @@ def _createEdgeCurve(p1, p2, curve, sense): _edgeCurves[key] = ec return ec -def _exportList_(a): +def _exportInternalList_(a): step = '' for i in a: if (isinstance(i, ExportEntity)): step += i.exportSTEP() elif (type(i) == list): - step += _exportList_(i) + step += _exportInternalList_(i) elif (type(i) == tuple): - step += _exportList_(i) + step += _exportInternalList_(i) return step def _createCurveComp(acisCurve): - # TODO - return acisCurve + # TODO + return None def _createCurveDegenerate(acisCurve): - # TODO - return acisCurve + # TODO + return None def _createCurveEllipse(acisCurve): global _ellipses @@ -246,57 +282,162 @@ def _createCurveEllipse(acisCurve): _ellipses[key] = circle return circle -def _createCurveInt(acisCurve): - global _curveBSplines - shape = acisCurve.build() - if (isinstance(shape, Part.Edge)): - bsc = shape.Curve - if (isinstance(bsc, Part.BSplineCurve)): - points = [_createCartesianPoint(v, 'Ctrl Pts') for v in bsc.getPoles()] - k1 = ",".join(["#%d"%(p.id) for p in points]) - k2 = "" - mults = bsc.getMultiplicities() - if (mults is not None): - k2 = ",".join(["%d" %(d) for d in mults]) - k3 = "" - knots = bsc.getKnots() - if (knots is not None): k3 = ",".join(["%r" %(r) for r in knots]) - key = "(%s),(%s),(%s)" %(k1, k2, k3) - try: - curve = _curveBSplines[key] - except: - if (bsc.isRational()): - p0 = BOUNDED_CURVE() - p1 = B_SPLINE_CURVE(name=None, degree=bsc.Degree, points=points, form='UNSPECIFIED', closed=bsc.isClosed(), selfIntersecting=False) - p2 = B_SPLINE_CURVE_WITH_KNOTS(mults=bsc.getMultiplicities(), knots=bsc.getKnots(), form2='UNSPECIFIED') - p3 = CURVE() - p4 = GEOMETRIC_REPRESENTATION_ITEM() - p5 = RATIONAL_B_SPLINE_CURVE(bsc.getWeights()) - p6 = REPRESENTATION_ITEM('') - curve = ListEntity(p0, p1, p2, p3, p4, p5, p6) - else: - curve = B_SPLINE_CURVE_WITH_KNOTS(name='', degree=bsc.Degree, points=points, form='UNSPECIFIED', closed=bsc.isClosed(), selfIntersecting=False, mults=bsc.getMultiplicities(), knots=bsc.getKnots(), form2='UNSPECIFIED') - _curveBSplines[key] = curve - return curve - if (isinstance(bsc, Part.Line)): - key = "%s,%s" %(bsc.Location, bsc.Direction) - try: - line = _lines[key] - except: - line = LINE('', None, None) - line.pnt = _createCartesianPoint(bsc.Location) - line.dir = _createVector(bsc.Direction) - _lines[key] = line - return line +def __create_b_spline_curve(spline): + if (spline): + points = [_createCartesianPoint(pole, 'Ctrl Pts') for pole in spline.poles] + k1 = ",".join(["#%d"%(point.id) for point in points]) + k2 = "" + mults = spline.uMults + if (mults): + k2 = ",".join(["%d" %(mult) for mult in mults]) + k3 = "" + knots = spline.uKnots + if (knots): + k3 = ",".join(["%r" %(knot) for knot in knots]) + key = "(%s),(%s),(%s)" %(k1, k2, k3) + try: + curve = _curveBSplines[key] + except: + degree = spline.uDegree + closed = (spline.poles[0] == spline.poles[-1]) + if (spline.rational): + p0 = BOUNDED_CURVE() + p1 = B_SPLINE_CURVE(name=None, degree=degree, points=points, form='UNSPECIFIED', closed=closed, selfIntersecting=False) + p2 = B_SPLINE_CURVE_WITH_KNOTS(mults=mults, knots=knots, form2='UNSPECIFIED') + p3 = CURVE() + p4 = GEOMETRIC_REPRESENTATION_ITEM() + p5 = RATIONAL_B_SPLINE_CURVE(spline.weights) + p6 = REPRESENTATION_ITEM('') + curve = ListEntity(p0, p1, p2, p3, p4, p5, p6) + else: + curve = B_SPLINE_CURVE_WITH_KNOTS(name='', degree=degree, points=points, form='UNSPECIFIED', closed=closed , selfIntersecting=False, mults=spline.uMults, knots=spline.uKnots, form2='UNSPECIFIED') + _curveBSplines[key] = curve + return curve + return None + +def _createCurveIntExact(acisCurve): +# acisCurve.spline +# acisCurve.singularity +# acisCurve.surface1# readSurface(chunks, i) +# acisCurve.surface2# readSurface(chunks, i) +# acisCurve.pcurve1 # readBS2Curve(chunks, i) +# acisCurve.pcurve2 # readBS2Curve(chunks, i) +# + __create_b_spline_curve(acisCurve.spline) + return curve + +def _createCurveIntBlend(acisCurve): + # TODO + return None + +def _createCurveIntBlendSpring(acisCurve): + # TODO + return None + +def _createCurveIntLaw(acisCurve): + # TODO + return None + +def _createCurveIntOff(acisCurve): + # TODO + return None + +def _createCurveIntOffset(acisCurve): + # TODO + return None + +def _createCurveIntOffsetSurface(acisCurve): + # TODO + return None + +def _createCurveIntSilhouetteParameter(acisCurve): + # TODO + return None + +def _createCurveIntParameter(acisCurve): + # TODO + return None + +def _createCurveIntProject(acisCurve): + # TODO + return None + +def _createCurveIntSurface(acisCurve): + # TODO + return None + +def _createCurveIntSilhouetteTaper(acisCurve): + # TODO + return None + +def _createCurveIntComp(acisCurve): + # TODO + return None + +def _createCurveIntDefm(acisCurve): + # TODO + return None + +def _createCurveIntHelix(acisCurve): + # TODO + return None + +def _createCurveIntSSS(acisCurve): + # TODO return None def _createCurveIntInt(acisCurve): - # TODO - return acisCurve + # TODO + return None + +CREATE_CURVE_INT ={ + 'bldcur': _createCurveIntBlend, + 'blend_int_cur': _createCurveIntBlend, + 'blndsprngcur': _createCurveIntBlendSpring, + 'spring_int_cur': _createCurveIntBlendSpring, + 'exactcur': _createCurveIntExact, + 'exact_int_cur': _createCurveIntExact, + 'lawintcur': _createCurveIntLaw, + 'law_int_cur': _createCurveIntLaw, + 'offintcur': _createCurveIntOff, + 'off_int_cur': _createCurveIntOff, + 'offsetintcur': _createCurveIntOffset, + 'offset_int_cur': _createCurveIntOffset, + 'offsurfintcur': _createCurveIntOffsetSurface, + 'off_surf_int_cur': _createCurveIntOffsetSurface, + 'parasil': _createCurveIntSilhouetteParameter, + 'para_silh_int_cur': _createCurveIntSilhouetteParameter, + 'parcur': _createCurveIntParameter, + 'par_int_cur': _createCurveIntParameter, + 'projcur': _createCurveIntProject, + 'proj_int_cur': _createCurveIntProject, +# 'd5c2_cur': _createCurveIntSkin, # !!!No examples available!!! +# 'skin_int_cur': _createCurveIntSkin, # !!!No examples available!!! +# 'subsetintcur': _createCurveIntSubset, # !!!No examples available!!! +# 'subset_int_cur': _createCurveIntSubset, # !!!No examples available!!! + 'surfcur': _createCurveIntSurface, + 'surf_int_cur': _createCurveIntSurface, + 'surfintcur': _createCurveIntInt, + 'int_int_cur': _createCurveIntInt, +# 'tapersil': _createCurveIntSilhouetteTaper, # !!!No examples available!!! +# 'taper_silh_int_cur': _createCurveIntSilhouetteTaper, # !!!No examples available!!! +## ASM Extensions ## + 'comp_int_cur': _createCurveIntComp, + 'defm_int_cur': _createCurveIntDefm, + 'helix_int_cur': _createCurveIntHelix, + 'sss_int_cur': _createCurveIntSSS, +} +def _createCurveInt(acisCurve): + try: + create = CREATE_CURVE_INT[acisCurve.subtype] + return create(acisCurve) + except: + logError("Don't know how how to create INT_CURVE %s!" %(acisCurve.subtype)) + return None def _createCurveP(acisCurve): - # TODO - return acisCurve + # TODO + return None def _createCurveStraight(acisCurve): global _lines @@ -390,7 +531,7 @@ def _createSurfaceCone(center, axis, cosine, sine, major, sense): cone = _cones[key] except: if (cosine * sine < 0): - plc = _createAxis2Placement3D('', center, 'Origin', axis.negative(), 'center_axis', major, 'ref_axis') + plc = _createAxis2Placement3D('', center, 'Origin', axis.negative(), 'center_axis', major, 'ref_axis') else: plc = _createAxis2Placement3D('', center, 'Origin', axis, 'center_axis', major, 'ref_axis') radius = major.Length @@ -433,7 +574,7 @@ def _createSurfaceRevolution(curve, center, axis, sense): ref = _calculateRef(axis) revolution = SURFACE_OF_REVOLUTION('', None, None) revolution.curve = _createCurve(curve) - revolution.placement = _createAxis2Placement3D('', center, 'Origin', axis, 'center_axis', ref, 'ref_axis') + revolution.placement = _createAxis2Placement3D('', center, 'Origin', axis, 'center_axis', ref, 'ref_axis') return revolution, (sense == 'forward') def _createSurfaceSphere(center, radius, pole, sense): @@ -455,16 +596,20 @@ def _createSurfaceToroid(major, minor, center, axis, sense): if (minor < 0.0): return torus, (sense != 'forward') return torus, (sense == 'forward') -def _createSurfaceFaceShape(acisFace, shape): - surface = acisFace._surface.getSurface() +def _createSurfaceFaceShape(acisFace): + surface = acisFace.getSurface() if (isinstance(surface, Acis.SurfaceCone)): return _createSurfaceCone(surface.center, surface.axis, surface.cosine, surface.sine, surface.major, acisFace.sense) +# if (isinstance(surface, Acis.SurfaceMesh)): +# return _createSurfaceMesh(surface.major, surface.minor, surface.center, surface.axis, acisFace.sense) if (isinstance(surface, Acis.SurfacePlane)): return _createSurfacePlane(surface.root, surface.normal, acisFace.sense) if (isinstance(surface, Acis.SurfaceSphere)): return _createSurfaceSphere(surface.center, surface.radius, surface.pole, acisFace.sense) if (isinstance(surface, Acis.SurfaceTorus)): return _createSurfaceToroid(surface.major, surface.minor, surface.center, surface.axis, acisFace.sense) + + shape = acisFace.build() if (isinstance(shape, Part.BSplineSurface)): return _createSurfaceBSpline(shape, surface, acisFace.sense) # if (isinstance(shape, Part.Mesh)): @@ -481,35 +626,26 @@ def _createSurfaceFaceShape(acisFace, shape): return _createSurfaceRevolution(surface.profile, surface.center, surface.axis, acisFace.sense) if (isinstance(shape, Part.Toroid)): return _createSurfaceToroid(surface.major, surface.minor, surface.center, surface.axis, acisFace.sense) - logWarning("Can't export surface '%s.%s'!" %(shape.__class__.__module__, shape.__class__.__name__)) - return None + logWarning("Can't export surface '%s.%s'!" %(surface.__class__.__module__, surface.__class__.__name__)) + return None, (acisFace.sense == 'forward') -def _createSurface(acisFace): - faces = [] - shape = acisFace.build() # will Return Face! - if (shape): - for face in shape.Faces: - f = _createSurfaceFaceShape(acisFace, face.Surface) - if (f): - faces.append(f) - return faces - -def _convertFace(acisFace, representation, parentColor, context): +def _convertFace(acisFace, parentColor, context): color = getColor(acisFace) if (color is None): color = parentColor - shells = [] - faces = _createSurface(acisFace) - for surface, sense in faces: + + surface, sense = _createSurfaceFaceShape(acisFace) + if (surface): face = ADVANCED_FACE('', surface, sense) face.bounds = _createBoundaries(acisFace.getLoops()) assignColor(color, face, context) - shells.append(face) + return face - return shells + return None -def _convertShell(acisShell, representation, shape, parentColor, transformation): +def _convertShell(acisShell, representation, parentColor): # FIXME how to distinguish between open or closed shell? + # MC: vedi OPEN_SHELL e CLOSED_SHELL, ma alla fine non le usa faces = acisShell.getFaces() if (len(faces) > 0): color = getColor(acisShell) @@ -517,37 +653,93 @@ def _convertShell(acisShell, representation, shape, parentColor, transformation) shell = OPEN_SHELL('',[]) for acisFace in faces: - faces = _convertFace(acisFace, representation, defColor, representation.context) - shell.faces += faces + face = _convertFace(acisFace, defColor, representation.context) + if (face): + shell.faces.append(face) - assignColor(defColor, shell, representation.context) + assignColor(defColor, shell, representation.context) return shell return None def _convertLump(acisLump, name, appContext, parentColor, transformation): - # TODO how to attach placement to a shell? + #MC: + #NOTA quando si volesse usare Part nativo, siccome li le trasformate le ho gia applicate, bastera esportare in STEP + + # Da OCCT + #product_definition + # A shape corresponding to the component type of for components. Each assembly or component has its own product_definition. It is used as a starting point for translation when read.step.product.mode is ON. + #product_definition_shape + # This entity provides a link between product_definition and corresponding shape_definition_representation, or between next_assembly_usage_occurence and corresponding context_dependent_shape_representation. + #shape_definition_representation + # A TopoDS_Compound for assemblies, a CASCADE shape corresponding to the component type for components. Each assembly or component has its own shape_definition_representation. The graph of dependencies is modified in such a way that shape_definition_representations of all components of the assembly are referred by the shape_definition_representation of the assembly. + #next_assembly_usage_occurence + # This entity defines a relationship between the assembly and its component. It is used to introduce (in the dependencies graph) the links between shape_definition_representation of the assembly and shape_definition_representations and context_dependent_shape_representations of all its components. + #context_dependent_shape_representation + # This entity is associated with the next_assembly_usage_occurence entity and defines a placement of the component in the assembly. The graph of dependencies is modified so that each context_dependent_shape_representation is referred by shape_definition_representation of the corresponding assembly. + #shape_representation_relationship_with_transformation + # This entity is associated with context_dependent_shape_representation and defines a transformation necessary to apply to the component in order to locate it in its place in the assembly. + #item_defined_transformation + # This entity defines a transformation operator used by shape_representation_relationship_with_transformation or mapped_item entity name = "%s_L_%02d" %(name, acisLump.index) - shape = SHAPE_DEFINITION_REPRESENTATION(name, appContext) - - shapeRepresentation = SHAPE_REPRESENTATION() - lump = SHELL_BASED_SURFACE_MODEL() - shapeRepresentation.items.append(lump) + frames = [PRODUCT_CONTEXT('', appContext, 'mechanical')] + prod = PRODUCT(name, frames) + prod_def_form = PRODUCT_DEFINITION_FORMATION(name + '_def_form', prod) + prod_def_ctx = PRODUCT_DEFINITION_CONTEXT(name + '_def_ctx', appContext, 'design') + prod_transf_def = PRODUCT_DEFINITION(name, prod_def_form, prod_def_ctx) + prod_def_shape = PRODUCT_DEFINITION_SHAPE(name + '_def_shape', '', prod_transf_def) + shapeOriginalWithProductInfo = SHAPE_DEFINITION_REPRESENTATION(name, prod_def_shape) unit = _createUnit(1e-7) - shapeRepresentation.context = unit - shape.representation = shapeRepresentation + lump = SHELL_BASED_SURFACE_MODEL() color = getColor(acisLump) defColor = parentColor if (color is None) else color + assignColor(defColor, lump, unit) + if ((not transformation is None) and (_isIdentity(transformation)==False)): + placement = TRANSFORM_NONE.Base + zDir = DIR_Z + xDir = DIR_X + ident_transf = _createAxis2Placement3D('', placement, '', zDir, '', xDir, '') + + advShapeRepresentation = ADVANCED_BREP_SHAPE_REPRESENTATION('', [], unit) + advShapeRepresentation.items.append(lump) + advShapeRepresentation.items.append(ident_transf) # a rhino basta questo con la trasformata effettiva, senza relazioni niente + + placement = transformation.Base + zDir = _rotate(DIR_Z, transformation.Rotation) + xDir = _rotate(DIR_X, transformation.Rotation) + transf = _createAxis2Placement3D('', placement, '', zDir, '', xDir, '') + + # rappresentazione contenente tutte le trasformate utilizzate nelle istanze + shapeRepresentation_trsfs = SHAPE_REPRESENTATION(unit) + shapeRepresentation_trsfs.items.append(ident_transf) + shapeRepresentation_trsfs.items.append(transf) + + idt = ITEM_DEFINED_TRANSFORMATION('', None, ident_transf, transf) + rr_transf = _createTransformation(advShapeRepresentation, shapeRepresentation_trsfs, idt) + prod_transf = PRODUCT('', frames) + prod_transf_def_form = PRODUCT_DEFINITION_FORMATION(prod_transf.name + '_trans_def_form', prod_transf) + prod_transf_def = PRODUCT_DEFINITION(prod.name + '_trans_def', prod_transf_def_form, prod_def_ctx) + prod_transf_def_shape = PRODUCT_DEFINITION_SHAPE(name + '_transdef_shape', '', prod_transf_def) + shapeToBeTransformed = SHAPE_DEFINITION_REPRESENTATION(name, prod_transf_def_shape) + shapeToBeTransformed.representation = advShapeRepresentation + nas = NEXT_ASSEMBLY_USAGE_OCCURRENCE(name + '_inst', name + '_inst', '', shapeOriginalWithProductInfo.definition.definition, shapeToBeTransformed.definition.definition) + prod_def_shape = PRODUCT_DEFINITION_SHAPE(None, None, nas) + CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(rr_transf, prod_def_shape) + shapeRet = shapeToBeTransformed + else: + shapeRepresentation = SHAPE_REPRESENTATION(unit) + shapeRepresentation.items.append(lump) + shapeOriginalWithProductInfo.representation = shapeRepresentation + shapeRet = shapeOriginalWithProductInfo + for acisShell in acisLump.getShells(): - shell = _convertShell(acisShell, shapeRepresentation, shape, defColor, transformation) + shell = _convertShell(acisShell, shapeRet.representation, defColor) if (shell is not None): lump.items.append(shell) - assignColor(defColor, lump, unit) - - return shape + return shapeRet def _convertBody(acisBody, appPrtDef): bodies = [] @@ -620,11 +812,11 @@ def _setExported(l, b): if ((type(l) == dict) or (type(l) == list)): for p in l: if (isinstance(p, ExportEntity)): - p.isexported = b + p.has_been_exported = b else: - l[p].isexported = b + l[p].has_been_exported = b if (isinstance(l, ExportEntity)): - l.isexported = b + l.has_been_exported = b def _exportList(l): step = u'' @@ -681,7 +873,7 @@ def __repr__(self): class ExportEntity(AnonymEntity): def __init__(self): super(ExportEntity, self).__init__() - self.isexported = False + self.has_been_exported = False def _getClassName(self): return self.__class__.__name__ def exportProperties(self): @@ -692,14 +884,14 @@ def exportProperties(self): if (isinstance(a, ReferencedEntity)): step += a.exportSTEP() elif (type(a) == list): - step += _exportList_(a) + step += _exportInternalList_(a) elif (type(a) == tuple): - step += _exportList_(a) + step += _exportInternalList_(a) except: logError(traceback.format_exc()) return step def exportSTEP(self): - if (self.isexported): + if (self.has_been_exported): return '' step = u"" if (hasattr(self, '__acis__')): @@ -709,7 +901,7 @@ def exportSTEP(self): step += u"/*\n * $%d\n */\n" %(self.__acis__.index) step += u"%s;\n" %(self.__repr__()) step += self.exportProperties() - self.isexported = True + self.has_been_exported = True return step class ReferencedEntity(ExportEntity): @@ -800,15 +992,44 @@ def __init__(self, name, products): def _getParameters(self): return super(PRODUCT_RELATED_PRODUCT_CATEGORY, self)._getParameters() + [self.description, self.products] +class PRODUCT_DEFINITION_RELATIONSHIP(NamedEntity): + def __init__(self, identifier = None, name = None, description = None, relating_product_definition = None, related_product_definition = None): + super(PRODUCT_DEFINITION_RELATIONSHIP, self).__init__(name) + self.identifier = identifier + self.description = description + self.relating_product_definition = relating_product_definition + self.related_product_definition = related_product_definition + def _getParameters(self): + return super(PRODUCT_DEFINITION_RELATIONSHIP, self)._getParameters() + [self.identifier, self.description, self.relating_product_definition, self.related_product_definition] + +class PRODUCT_DEFINITION_USAGE(PRODUCT_DEFINITION_RELATIONSHIP): + def __init__(self, identifier = None, name = None, description = None, relating_product_definition = None, related_product_definition = None): + super(PRODUCT_DEFINITION_USAGE, self).__init__(identifier, name, description, relating_product_definition, related_product_definition) + def _getParameters(self): + return super(PRODUCT_DEFINITION_USAGE, self)._getParameters() + +class ASSEMBLY_COMPONENT_USAGE(PRODUCT_DEFINITION_USAGE): + def __init__(self, identifier = None, name = None, description = None, relating_product_definition = None, related_product_definition = None, reference_designator = None): + super(ASSEMBLY_COMPONENT_USAGE, self).__init__(identifier, name, description, relating_product_definition, related_product_definition) + self.reference_designator = reference_designator + def _getParameters(self): + return super(ASSEMBLY_COMPONENT_USAGE, self)._getParameters() + [self.reference_designator] + +class NEXT_ASSEMBLY_USAGE_OCCURRENCE(ASSEMBLY_COMPONENT_USAGE): + def __init__(self, identifier = None, name = None, description = None, relating_product_definition = None, related_product_definition = None, reference_designator = None): + super(NEXT_ASSEMBLY_USAGE_OCCURRENCE, self).__init__(identifier, name, description, relating_product_definition, related_product_definition, reference_designator) + def _getParameters(self): + return super(NEXT_ASSEMBLY_USAGE_OCCURRENCE, self)._getParameters() + class PRODUCT(ReferencedEntity): - def __init__(self, name, context = APPLICATION_CONTEXT()): + def __init__(self, name, frames): super(PRODUCT, self).__init__() - self.identifyer = name + self.identifier = name self.name = name self.description = '' - self.frames = [PRODUCT_CONTEXT('', context, 'mechanical')] + self.frames = frames def _getParameters(self): - return super(PRODUCT, self)._getParameters() + [self.identifyer, self.name, self.description, self.frames] + return super(PRODUCT, self)._getParameters() + [self.identifier, self.name, self.description, self.frames] class PRODUCT_CONTEXT(NamedEntity): def __init__(self, name = 'part definition', frame = None, discipline = 'mechanical'): @@ -898,7 +1119,7 @@ def _getParameters(self): params = sorted(params) return params def exportSTEP(self): - if (self.isexported): + if (self.has_been_exported): return '' step = u"" if (hasattr(self, '__acis__')): @@ -912,12 +1133,12 @@ def exportSTEP(self): if (isinstance(e, ExportEntity)): step += e.exportProperties() elif (type(e) == list): - step += _exportList_(e) + step += _exportInternalList_(e) elif (type(e) == tuple): - step += _exportList_(e) + step += _exportInternalList_(e) except: logError(traceback.format_exc()) - self.isexported = True + self.has_been_exported = True return step def __repr__(self): return u"#%d\t= (%s)" %(self.id, " ".join(["%s" % (e.toString()) for e in self.entities])) @@ -930,7 +1151,7 @@ class NAMED_UNIT(ExportEntity): def __init__(self, dimensions): super(NAMED_UNIT, self).__init__() self.dimensions = dimensions - self.isexported = True + self.has_been_exported = True def _getParameters(self): l = super(NAMED_UNIT, self)._getParameters() if (self.dimensions is not None): @@ -941,6 +1162,69 @@ class LENGTH_UNIT(NAMED_UNIT): def __init__(self, dimensions): super(LENGTH_UNIT, self).__init__(dimensions) +class REPRESENTATION_RELATIONSHIP(NamedEntity): + def __init__(self, descr = None, repr1 = None, repr2 = None): + super(REPRESENTATION_RELATIONSHIP, self).__init__() + self.description = descr + self.repr1 = repr1 + self.repr2 = repr2 + self.has_been_exported = True # fa parte di una listEntity + def _getParameters(self): + return super(REPRESENTATION_RELATIONSHIP, self)._getParameters() + [self.description, self.repr1, self.repr2] + +#The entity shape_representation_relationship_is a subtype of representation_relationship. The subtype adds +#specific local constraints that ensures that it defines a relationship between two shape_representations. To +#define a relationship between two shape_representations that is established via a transformation, a complex +#instantiation of shape_representation_relationship AND representation_relationship_with_transformation is +#used. +class SHAPE_REPRESENTATION_RELATIONSHIP(REPRESENTATION_RELATIONSHIP): + def __init__(self, repr1 = None, repr2 = None): + super(SHAPE_REPRESENTATION_RELATIONSHIP, self).__init__(repr1, repr2) + self.has_been_exported = True # fa parte di una listEntity + def _getParameters(self): + return [] # nella pratica shape_representation_relationship e sempre senza argomenti + +#The entity representation_relationship_with_transformation_is a subtype of representation_relationship. +#The subtype adds the attribute transformation_operator as a reference to a transformation. To define a +#relationship between two shape_representations that is established via a transformation, a complex +#instantiation of shape_representation_relationship AND representation_relationship_with_transformation is +#used. +#NOTA peccato che nella pratica shape_representation_relationship sia sempre senza argomenti +class REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(REPRESENTATION_RELATIONSHIP): + def __init__(self, transform): + super(REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION, self).__init__() + self.transform = transform + self.has_been_exported = True # fa parte di una listEntity + def _getParameters(self): + return [self.transform] # MC non mi interessa del resto + +#An item_defined_transformation models a transformation performed by defining two representation_items +#before and after applying the transformation function The transformation function is not explicitly +#provided, but it is derived through its relationship to the representation_items. +class ITEM_DEFINED_TRANSFORMATION(NamedEntity): + def __init__(self, name = '', description = None, trans_before = None, trans_after = None): + self.description = description + self.trans_before = trans_before + self.trans_after = trans_after + super(ITEM_DEFINED_TRANSFORMATION, self).__init__(name) + def _getParameters(self): + return super(ITEM_DEFINED_TRANSFORMATION, self)._getParameters() + [self.description, self.trans_before, self.trans_after] + +#The relationships between the assembly and the component on the product_definition level and the shape_- +#representation level has to be linked through a context_dependent_shape_representation. This is necessary +#to distinguish between several occurrences of the same component within an assembly +#A context_dependent_shape_representation associates a shape_representation_relationship with a product_- +#definition_shape. In the given context this allows the explicit specification of a shape of the assembly 'as +#assembled'. Since elements when assembled might change their shape - e.g., under pressure - this +#representation may differ from the geometric assembly of the individual shapes. +class CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(ExportEntity): + def __init__(self, shape_unassembled = None, shape_assembled = None): + super(CONTEXT_DEPENDENT_SHAPE_REPRESENTATION, self).__init__() + self.shape_unassembled = shape_unassembled + self.shape_assembled = shape_assembled + def _getParameters(self): + return [self.shape_unassembled, self.shape_assembled] # MC non mi interessa di scrivere il nome + class SOLID_ANGLE_UNIT(NAMED_UNIT): def __init__(self, dimensions): super(SOLID_ANGLE_UNIT, self).__init__(dimensions) @@ -978,12 +1262,12 @@ def __init__(self, value): class GEOMETRIC_REPRESENTATION_CONTEXT(ValueObject): def __init__(self, value): super(GEOMETRIC_REPRESENTATION_CONTEXT, self).__init__(value) - self.isexported = True + self.has_been_exported = True class LENGTH_MEASURE(ValueObject): def __init__(self, value): super(LENGTH_MEASURE, self).__init__(value) - self.isexported = True + self.has_been_exported = True class UNCERTAINTY_MEASURE_WITH_UNIT(ReferencedEntity): def __init__(self, value, length): @@ -999,7 +1283,7 @@ class GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT(ExportEntity): def __init__(self): super(GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT, self).__init__() self.units = [] - self.isexported = True + self.has_been_exported = True def _getParameters(self): return super(GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT, self)._getParameters() + [self.units] @@ -1007,18 +1291,18 @@ class GLOBAL_UNIT_ASSIGNED_CONTEXT(ExportEntity): def __init__(self): super(GLOBAL_UNIT_ASSIGNED_CONTEXT, self).__init__() self.assignments = [] - self.isexported = True + self.has_been_exported = True def _getParameters(self): return super(GLOBAL_UNIT_ASSIGNED_CONTEXT, self)._getParameters() + [self.assignments] class REPRESENTATION_CONTEXT(ExportEntity): - def __init__(self, identifyer = '', t = '3D'): + def __init__(self, identifier = '', t = '3D'): super(REPRESENTATION_CONTEXT, self).__init__() - self.identifyer = identifyer + self.identifier = identifier self.type = t - self.isexported = True + self.has_been_exported = True def _getParameters(self): - return super(REPRESENTATION_CONTEXT, self)._getParameters() + [self.identifyer, self.type] + return super(REPRESENTATION_CONTEXT, self)._getParameters() + [self.identifier, self.type] class PLANE_ANGLE_MEASURE_WITH_UNIT(ReferencedEntity): def __init__(self, value): @@ -1096,30 +1380,39 @@ def _getParameters(self): return super(APPLIED_DATE_AND_TIME_ASSIGNMENT, self)._getParameters() + [self.datetime, self.role, self.products] class PRODUCT_DEFINITION_SHAPE(NamedEntity): - def __init__(self, name, context): - super(PRODUCT_DEFINITION_SHAPE, self).__init__() - self.description = '' - self.definition = PRODUCT_DEFINITION(name, context) + def __init__(self, name = None, description = None, definition = None): + super(PRODUCT_DEFINITION_SHAPE, self).__init__(name) + self.description = description + self.definition = definition def _getParameters(self): return super(PRODUCT_DEFINITION_SHAPE, self)._getParameters() + [self.description, self.definition] -class SHAPE_REPRESENTATION(NamedEntity): - def __init__(self): - super(SHAPE_REPRESENTATION, self).__init__('') +class REPRESENTATION(NamedEntity): + def __init__(self, context): + super(REPRESENTATION, self).__init__('') + #The items attribute collects the items of the shape_representation. self.items = [] - self.context = None + # The context_of_items attribute references a geometric_representation_context that establishes + # the coordinate space for the shape_representation + self.context = context + def _getParameters(self): + return super(REPRESENTATION, self)._getParameters() + [self.items, self.context] + +class SHAPE_REPRESENTATION(REPRESENTATION): + def __init__(self, context): + super(SHAPE_REPRESENTATION, self).__init__(context) def _getParameters(self): - return super(SHAPE_REPRESENTATION, self)._getParameters() + [self.items, self.context] + return super(SHAPE_REPRESENTATION, self)._getParameters() class MANIFOLD_SURFACE_SHAPE_REPRESENTATION(SHAPE_REPRESENTATION): def __init__(self): super(MANIFOLD_SURFACE_SHAPE_REPRESENTATION, self).__init__() class SHAPE_DEFINITION_REPRESENTATION(ReferencedEntity): - def __init__(self, name, context): + def __init__(self, name, definition = None, representation = None): super(SHAPE_DEFINITION_REPRESENTATION, self).__init__() - self.definition = PRODUCT_DEFINITION_SHAPE(name, context) - self.representation = None + self.definition = definition + self.representation = representation def _getParameters(self): return super(SHAPE_DEFINITION_REPRESENTATION, self)._getParameters() + [self.definition, self.representation] def getProduct(self): @@ -1128,10 +1421,10 @@ def getAppContext(self): return self.definition.definition.frame.context class PRODUCT_DEFINITION_FORMATION(NamedEntity): - def __init__(self, name, context): - super(PRODUCT_DEFINITION_FORMATION, self).__init__('') + def __init__(self, name, product): + super(PRODUCT_DEFINITION_FORMATION, self).__init__(name) self.description = '' - self.product = PRODUCT(name, context) + self.product = product def _getParameters(self): return super(PRODUCT_DEFINITION_FORMATION, self)._getParameters() + [self.description, self.product] @@ -1144,11 +1437,11 @@ def _getParameters(self): return super(PRODUCT_DEFINITION_CONTEXT, self)._getParameters() + [self.context, self.stage] class PRODUCT_DEFINITION(NamedEntity): - def __init__(self, name, context): - super(PRODUCT_DEFINITION, self).__init__('design') + def __init__(self, name, formation, context): + super(PRODUCT_DEFINITION, self).__init__(name) self.description = '' - self.formation = PRODUCT_DEFINITION_FORMATION(name, context) - self.frame = PRODUCT_DEFINITION_CONTEXT('part definition', context, 'design') + self.formation = formation + self.frame = context def _getParameters(self): return super(PRODUCT_DEFINITION, self)._getParameters() + [self.description, self.formation, self.frame] @@ -1168,15 +1461,6 @@ class ADVANCED_BREP_SHAPE_REPRESENTATION(ItemsRepresentationEntity): def __init__(self, name, items, context): super(ADVANCED_BREP_SHAPE_REPRESENTATION, self).__init__(name, items, context) -class SHAPE_REPRESENTATION_RELATIONSHIP(NamedEntity): - def __init__(self, name, description, rep1, rep2): - super(SHAPE_REPRESENTATION_RELATIONSHIP, self).__init__(name) - self.description = description - self.rep1 = rep1 - self.rep2 = rep2 - def _getParameters(self): - return super(SHAPE_REPRESENTATION_RELATIONSHIP, self)._getParameters() + [self.description, self.rep1, self.rep2] - class CLOSED_SHELL(NamedEntity): def __init__(self, name, faces): super(CLOSED_SHELL, self).__init__(name) @@ -1450,7 +1734,7 @@ def export(filename, satHeader, satBodies): user = getAuthor() desc = getDescription() orga = '' - proc = 'InventorImporter 0.9' + proc = 'InventorImporter' auth = '' _initExport() @@ -1459,11 +1743,12 @@ def export(filename, satHeader, satBodies): _scale = satHeader.scale appPrtDef = APPLICATION_PROTOCOL_DEFINITION() - bodies = [] + for body in satBodies: body.name = filename - bodies += _convertBody(body, appPrtDef) - PRODUCT_RELATED_PRODUCT_CATEGORY('part', bodies) + part = _convertBody(body, appPrtDef) + # MC: fanno tutti 1 body -> 1 parte + PRODUCT_RELATED_PRODUCT_CATEGORY('part', part) path, f = os.path.split(filename) name, x = os.path.splitext(f) @@ -1494,7 +1779,6 @@ def export(filename, satHeader, satBodies): with io.open(stepfile, 'wt', encoding="UTF-8") as stepFile: stepFile.write(step) -# logAlways(u"STEP file written to '%s'.", stepfile) logInfo(u"STEP file written to '%s'.", stepfile) _finalizeExport() diff --git a/importerConstants.py b/importerConstants.py index c833914..3fb977f 100644 --- a/importerConstants.py +++ b/importerConstants.py @@ -47,3 +47,5 @@ DIR_Z = VEC(0, 0, 1) ENCODING_FS = 'utf8' + +EPS = 1.0e-6 \ No newline at end of file diff --git a/importerFreeCAD.py b/importerFreeCAD.py index dedf7e4..9d09529 100644 --- a/importerFreeCAD.py +++ b/importerFreeCAD.py @@ -1,21 +1,21 @@ # -*- coding: utf-8 -*- +__author__ = 'Jens M. Plonka' +__copyright__ = 'Copyright 2023, Germany' +__url__ = "https://www.github.com/jmplonka/InventorLoader" + ''' importerFreeCAD.py ''' -import sys, FreeCAD, Draft, Part, Sketcher, traceback, Mesh, InventorViewProviders, Acis, re +import FreeCAD, Draft, Part, Sketcher, traceback, Mesh, InventorViewProviders, Acis, re from importerClasses import * from importerUtils import * from importerSegNode import SecNode, SecNodeRef, setParameter -from math import sqrt, tan, degrees, pi -from FreeCAD import Vector as VEC, Rotation as ROT, Placement as PLC, Version, ParamGet +from math import sqrt, tan, degrees, pi, asin +from FreeCAD import Vector as VEC, Rotation as ROT, Placement as PLC, ParamGet from importerConstants import CENTER, DIR_X, DIR_Y, DIR_Z -__author__ = 'Jens M. Plonka' -__copyright__ = 'Copyright 2018, Germany' -__url__ = "https://www.github.com/jmplonka/InventorLoader" - BIT_GEO_ALIGN_HORIZONTAL = 1 << 0 BIT_GEO_ALIGN_VERTICAL = 1 << 1 BIT_GEO_BEND = 1 << 2 @@ -162,7 +162,7 @@ def newObject(className, name, body = None): body.addObject(obj) except: obj.adjustRelativeLinks(body) - body.ViewObject.dropObject(obj, None, '', []) + body.ViewObject.dropObject(obj, None, name, []) return obj def createGroup(name): @@ -282,11 +282,10 @@ def getDimension(node, varName): dimension = node.get(varName) if (dimension.typeName == 'Line2D'): - dimension = DimensionValue(Length(getLengthLine(dimension))) + dimension = Length(getLengthLine(dimension)) elif (dimension.typeName == 'Point2D'): - dimension = DimensionValue(Length(0)) - - if (dimension.typeName != 'Parameter'): + dimension = Length(0) + elif (dimension.typeName != 'Parameter'): logError(u"Expected Dimension for (%04X): %s - NOT %s", node.index, node.typeName, dimension.typeName) return dimension @@ -528,7 +527,7 @@ def adjustFxColor(entity, nodColor): return def __hide__(geo): - if (geo is not None): + if (geo): geo.ViewObject.Visibility = False return @@ -832,7 +831,7 @@ def findBase(self, base): if (name in self.bodyNodes): baseGeo = self.getGeometry(self.bodyNodes[name]) if (baseGeo is None): - logWarning(u" Base2 (%04X): %s -> (%04X): %s can't be created!", base.index, baseNode.typeName, bodyNode.index, bodyNode.typeName) + logWarning(u" Base2 = '%s' -> (%04X): %s can't be created!", name, base.index, base.typeName) else: logInfo(u" ... Base2 = '%s'", name) else: @@ -860,7 +859,7 @@ def findGeometries(self, node): # ensure that the sketch is already created! toolGeo = self.getGeometry(self.bodyNodes[name]) if (toolGeo is None): - logWarning(u" Tool (%04X): %s -> (%04X): %s can't be created", node.index, node.typeName, toolData.index, toolData.typeName) + logWarning(u" Tool = '%s' -> (%04X): %s can't be created", name, node.index, node.typeName) else: geometries.append(toolGeo) logInfo(u" ... Tool = '%s'", name) @@ -1429,12 +1428,12 @@ def addSketch_Geometric_SymmetryPoint2D(self, constraintNode, sketchObj): if ((lineIdx is None) or (lineIdx < 0)): logWarning(u" ... can't added symmetric constraint between Point and %s - no line index for (%04X)!", moving.typeName[0:-2], moving.index) - elif ((symmetryIdx is None) or (symmetryIdx < 0) or (symmetryPos < -1)): + elif ((symmetryIdx is None) or (symmetryIdx < 0) or (symmetryIdx < -1)): logWarning(u" ... can't added symmetric constraint between Point and %s - no point index for (%04X)!", moving.typeName[0:-2], constraintNode.get('point').index) else: key = 'SymmetryPoint_%s_%s' %(lineIdx, symmetryIdx) if (not key in self.mapConstraints): - constraint = Sketcher.Constraint('Symmetric', lineIdx, 1, lineIdx, 2, symmetryIdx, symmetryPos) + constraint = Sketcher.Constraint('Symmetric', lineIdx, 1, lineIdx, 2, symmetryIdx, symmetryIdx) index = self.addConstraint(sketchObj, constraint, key) constraintNode.setGeometry(constraint, index) logInfo(u" ... added symmetric constraint between Point %s and %s %s", symmetryIdx, moving.typeName[0:-2], lineIdx) @@ -2714,7 +2713,7 @@ def Create_FxClient(self, clientNode): # create a subfolder name = InventorViewProviders.getObjectName(clientNode.name) if ((name is None) or (len(name) == 0)): - name = node.typeName + name = clientNode.typeName fx = createGroup(name) # add/move all objects to this folder diff --git a/importerReader.py b/importerReader.py index 655b258..7c4f34a 100644 --- a/importerReader.py +++ b/importerReader.py @@ -5,7 +5,7 @@ Simple approach to read/analyse Autodesk (R) Invetor (R) files. ''' -import sys, os, uuid, datetime, re, zlib, operator, glob, struct, codecs, xlrd, FreeCAD, Import_IPT, importerOle10Nateive +import zlib, codecs, xlrd, importerOle10Nateive from importerClasses import * from importerSegment import SegmentReader from importerApp import AppReader @@ -253,7 +253,7 @@ def ReadProtein(data): def ReadWorkbook(data, name, stream): dumpFolder = getDumpFolder() - if (not (dumpFolder is None)): + if (dumpFolder): ##create a new Spreadsheet in new document wbk = xlrd.book.open_workbook_xls(file_contents=data, formatting_info=True) for nameValues in wbk.name_obj_list: diff --git a/importerSAT.py b/importerSAT.py index e567c85..cdf8ad3 100644 --- a/importerSAT.py +++ b/importerSAT.py @@ -5,11 +5,11 @@ Collection of classes necessary to read and analyse Autodesk (R) Invetor (R) files. ''' -import os, sys, tokenize, FreeCAD, Part, re, traceback, datetime, ImportGui, io -from importerUtils import logInfo, logWarning, logError, logAlways, getUInt8A, getUInt32, chooseImportStrategyAcis, STRATEGY_SAT, STRATEGY_NATIVE, STRATEGY_STEP, setDumpFolder, getDumpFolder +from msilib import CreateRecord +import os, FreeCAD, Part, ImportGui, io +from importerUtils import logInfo, logAlways, chooseImportStrategyAcis, STRATEGY_SAT, STRATEGY_NATIVE, STRATEGY_STEP, setDumpFolder, getDumpFolder from Acis2Step import export -from math import fabs -from Acis import TAG_ENTITY_REF, getReader, setReader, AcisReader, AcisChunkPosition, setVersion, createNode, init +from Acis import TAG_ENTITY_REF, getReader, setReader, AcisReader, createEntity, init __author__ = 'Jens M. Plonka' __copyright__ = 'Copyright 2018, Germany' @@ -127,12 +127,12 @@ def resolveNodes(acis): if (getDumpFolder()[-3:].lower() != 'sat'): name = _getSatFileName(acis.name) dumpSat(name, acis) - for entity in acis.getEntities(): - node = createNode(entity) - if (node): - if (doAdd and (entity.name == 'body')): - bodies.append(node) - if (entity.name in ['Begin-of-ACIS-History-Data', 'End-of-ACIS-data']): + for record in acis.getRecords(): + entity = createEntity(record) + if entity: + if (doAdd and (record.name == 'body')): + bodies.append(entity) + if (record.name in ['Begin-of-ACIS-History-Data', 'End-of-ACIS-data']): doAdd = False return bodies @@ -187,7 +187,6 @@ def create3dModel(group, doc): def dumpSat(name, acis, use_dump_folder = True): header = acis.header history = acis.history - entities = acis.getEntities() dumpFolder = getDumpFolder() historyIdx = None @@ -201,7 +200,7 @@ def dumpSat(name, acis, use_dump_folder = True): satFile = name with io.open(satFile, 'wt', encoding='utf-8') as sat: sat.write(header.__str__()) - for record in entities: + for record in acis.getRecords(): if (record.index == historyIdx): sat.write(u"%r\n"%(history.getRecord())) for ds in history.delta_states: diff --git a/importerSegment.py b/importerSegment.py index 6c84f19..ae55fa4 100644 --- a/importerSegment.py +++ b/importerSegment.py @@ -11,7 +11,7 @@ from importerTransformation import Transformation2D, Transformation3D from importerSegNode import isList, CheckList, SecNode, SecNodeRef, _TYP_NODE_REF_, _TYP_UINT32_A_, REF_PARENT, REF_CHILD, REF_CROSS from importerUtils import * -from Acis import clearEntities, AcisReader, setVersion, TAG_ENTITY_REF, getInteger, createNode, getNameMatchAttributes, getDcAttributes +from Acis import clearEntities, AcisReader, setVersion, TAG_ENTITY_REF, createEntity, getNameMatchAttributes, getDcAttributes from importerSAT import dumpSat from uuid import UUID import importerUtils @@ -28,8 +28,8 @@ def resolveEntityReferences(node): acis = node.get('SAT') try: # create a node for each entity - for entity in acis.getEntities(): - createNode(entity) + for record in acis.getRecords(): + createEntity(record) dumpSat("%04X" %(node.index), acis) # resolve the roll-back information from the history diff --git a/importerUtils.py b/importerUtils.py index 45339b6..05e13d9 100644 --- a/importerUtils.py +++ b/importerUtils.py @@ -11,7 +11,7 @@ from struct import Struct, unpack_from, pack from FreeCAD import Vector as VEC, Console, ParamGet from olefile import OleFileIO -from importerConstants import ENCODING_FS +from importerConstants import ENCODING_FS, CENTER __author__ = 'Jens M. Plonka' __copyright__ = 'Copyright 2018, Germany' @@ -232,6 +232,7 @@ def setAuthor(author): return def getAuthor(): + global _author return _author def setCompany(company): @@ -924,11 +925,7 @@ def PrintableName(fname): def decode(filename, utf=False): if (isinstance(filename, unicode)): # workaround since ifcopenshell currently can't handle unicode filenames - if (utf): - encoding = "utf8" - else: - import sys - encoding = sys.getfilesystemencoding() + encoding = ENCODING_FS if (utf) else sys.getfilesystemencoding() filename = filename.encode(encoding).decode("utf-8") return filename