Comments (11)
Please check out this version that, by merging new and old approach, provides what follows:
-
bug fixes in STEP transformation
-
** Online Autodesk dxf viewer didn't show the transformed elements at all (while FreeCAD, Rhino and ShareCAD did)
-
** Translations only sometimes result in a (0, 0, 0) rotation axis, which cannot be normalized
-
Demo-Status-0.4.2.ipt works with native Part (no stubs)
-
Demo-Status-0.6.ipt works with native Part (no stubs)
-
Fixed syntax errors found compiling with Cython
from inventorloader.
From the -dbg version, implement this snippet below in Part.py, class BSplineCurve(Curve). Then, in Acis.py you transform the single points before interpolating, instead of rotating the whole spline once built. Let me know how it works.
from geomdl import fitting, BSpline as NURBSBSpline
[...]
class BSplineCurve(Curve):
def __init__(self, points = [], weights = None, knots = None, periodic = False, degree = 3, multiplicities = None, checkrational = False):
super(BSplineCurve, self).__init__('BSplineCurve')
self._poles = points
self._weights = weights
self.KnotSequence = knots
self._closed = periodic
self._mults = multiplicities
self._knotsExploded = []
if not knots is None:
for i in range(0, len(knots)):
for m in range(0, multiplicities[i]):
self._knotsExploded.append(knots[i])
self.Degree = degree
self.bSplineCurve = None
def getPoles(self):
return self._poles
def getMultiplicities(self):
nb_knots = len(self._knotsExploded)
if (nb_knots == 0):
return []
elif (nb_knots == 1):
return [1]
else:
ret = []
mult = 1
i = 1
while i < nb_knots:
while (i < nb_knots and isclose(self._knotsExploded[i - 1], self._knotsExploded[i])):
mult += 1
i += 1
ret.append(mult)
mult = 1
i += 1
return ret
def getKnots(self):
return self.KnotSequence
def getWeights(self):
return self._weights
def isRational(self):
if (not self.bSplineCurve is None):
return self.bSplineCurve.rational
else:
return (self._weights is not None) and (len(self._weights) > 0)
def isClosed(self): return self._closed
def value(self, u):
#evaluate
if (not self.bSplineCurve is None):
value = self.bSplineCurve.evaluate_single(u)
return Vector(value.x, value.y, value.z)
def interpolate(self, points, periodicFlag=False, tolerance=1e-6, initialTangent=None, finalTangent=None, tangents=None, tangentFlags=False, parameters=None, scale=1.0):
pointsV = []
for p in points:
pointsV.append((p.x, p.y, p.z))
self.bSplineCurve = fitting.interpolate_curve(pointsV, self.Degree)
self._poles = []
for p in self.bSplineCurve.ctrlpts:
self._poles.append(Vector(p[0], p[1], p[2])) # lo stesso formato atteso
self._knotsExploded = self.bSplineCurve.knotvector
self.KnotSequence = []
nbKnots = len(self._knotsExploded)
if nbKnots > 0:
if nbKnots == 1:
self.KnotSequence = self._knotsExploded
else:
self.KnotSequence.append(self._knotsExploded[0])
i = 1
while i < nbKnots:
while (i < nbKnots and isclose(self._knotsExploded[i - 1], self._knotsExploded[i])):
i += 1
if (i < nbKnots):
self.KnotSequence.append(self._knotsExploded[i])
i += 1
startp = self.bSplineCurve.evaluate_single(self.KnotSequence[0])
startpV = Vector(startp[0], startp[1], startp[2])
endp = self.bSplineCurve.evaluate_single(self.KnotSequence[-1])
endpV = Vector(endp[0], endp[1], endp[2])
self._closed = startpV.distanceToPoint(endpV) < EPS
self._weights = parameters
def buildFromPolesMultsKnots(self, poles, mults=(), knots=(), periodic=False, degree=1, weights=None, CheckRational = True):
lu = len(poles)
sum_of_mults = sum(mults)
if (PyObject_IsTrue(periodic) and (sum_of_mults - degree - 1 != lu)): raise Exception("number of poles and sum of mults mismatch")
if (PyObject_Not(periodic) and (sum_of_mults - degree - 1 != lu)): raise Exception("number of poles and sum of mults mismatch")
if ((weights is not None) and (lu != len(weights))): raise Exception("number of poles and weights mismatch")
self._poles = poles
self._mults = mults
self.KnotSequence = knots
self._knotsExploded = []
for i in range(0, len(knots)):
for _ in range(0, mults[i]):
self._knotsExploded.append(knots[i])
self._closed = periodic
self.Degree = degree
self._weights = weights
self.bSplineCurve = NURBSBSpline.Curve()
self.bSplineCurve.degree = degree
self.bSplineCurve.weights = weights
self.bSplineCurve.ctrlpoints = poles
self.bSplineCurve.knotvector = self._knotsExploded
return self
from inventorloader.
class BSplineSurface(GeometrySurface):
def __init__(self):
super(BSplineSurface, self).__init__('BSplineSurface')
self._poles = []
self.UKnotSequence = []
self.VKnotSequence = []
self.UDegree = 3
self.VDegree = 3
self._weights = []
#MC
self._uknotsExploded = []
self._vknotsExploded = []
self.bSplineSurface = None
def getPoles(self): return self._poles
def getUMultiplicities(self):
nb_uknots = len(self._uknotsExploded)
if (nb_uknots == 0):
return []
elif (nb_uknots == 1):
return [1]
else:
ret = []
mult = 1
i = 1
while i < nb_uknots:
while (i < nb_uknots and isclose(self._uknotsExploded[i - 1], self._uknotsExploded[i])):
mult += 1
i += 1
ret.append(mult)
mult = 1
i += 1
return ret
def getVMultiplicities(self):
nb_vknots = len(self._vknotsExploded)
if (nb_vknots == 0):
return []
elif (nb_vknots == 1):
return [1]
else:
ret = []
mult = 1
i = 1
while i < nb_vknots:
while (i < nb_vknots and isclose(self._vknotsExploded[i - 1], self._vknotsExploded[i])):
mult += 1
i += 1
ret.append(mult)
mult = 1
i += 1
return ret
def getUKnots(self):
return self.UKnotSequence
def getVKnots(self):
return self.VKnotSequence
def isURational(self):
if (self.bSplineSurface is not None):
return self.bSplineSurface.rational
else:
return self._weights is not None and len(self._weights) > 0
def isVRational(self):
if (self.bSplineSurface is not None):
return self.bSplineSurface.rational
else:
return self._weights is not None and len(self._weights) > 0
def NbUKnots(self):
return len(self.UKnotSequence)
def NbVKnots(self):
return len(self.VKnotSequence)
def NbUPoles(self):
return len(self._poles)
def NbVPoles(self):
if (self.NbUPoles() > 0):
return len(self._poles[0])
else:
return 0
def NbPoles(self):
return len(self._poles)
def isUClosed(self):
isClosed = True
j = 0
while (isClosed and j < self.NbVPoles()):
isClosed = self._poles[0][j].distance(self._poles[-1][j]) <= EPS
j += 1
return isClosed
def isVClosed(self):
isClosed = True
i = 0
while (isClosed and i < self.NbUPoles()):
isClosed = self._poles[i][0].distance(self._poles[i][-1]) <= EPS
i += 1
return isClosed
def getWeights(self):
return self._weights
def buildFromPolesMultsKnots(self, poles, umults=(), vmults=(), uknots=(), vknots=(), uperiodic=False, vperiodic=False, udegree=1, vdegree=1, weights=None):
lu = len(poles)
sum_of_umults = sum(umults)
lv = len(poles[0])
sum_of_vmults = sum(vmults)
for i in umults:
for j in range(0, i):
self._uknotsExploded.append(uknots[i])
for i in vmults:
for j in range(0, i):
self._vknotsExploded.append(vknots[i])
if ((weights is not None) and (lu != len(weights))): raise Exception("weights and poles rows-mismatch")
if ((weights is not None) and (lv != len(weights[0]))): raise Exception("weights and poles cols-mismatch")
if (len(uknots) != len(umults)): raise Exception("number of u-knots and u-mults mismatch")
if (len(vknots) != len(vmults)): raise Exception("number of v-knots and v-mults mismatch")
#if (PyObject_IsTrue(uperiodic) and (sum_of_umults - udegree - 1 != lu)): raise Exception("number of poles (%d) and sum of u-mults (%d) mismatch for uPeriodic = True" %(lu, sum_of_umults))
#if (PyObject_IsTrue(vperiodic) and (sum_of_umults - udegree - 1 != lu)): raise Exception("number of poles (%d) and sum of v-mults (%d) mismatch for vPeriodic = True" %(lv, sum_of_vmults))
if (PyObject_Not(uperiodic) and (sum_of_umults - udegree - 1 != lu)): raise Exception("number of poles (%d) and sum of u-mults (%d) mismatch for uPeriodic = False" %(lu, sum_of_umults))
if (PyObject_Not(vperiodic) and (sum_of_vmults - vdegree - 1 != lv)): raise Exception("number of poles (%d) and sum of v-mults (%d) mismatch for vPeriodic = False" %(lv, sum_of_vmults))
self._poles = poles
self.UKnotSequence = uknots
self.VKnotSequence = vknots
self.UDegree = udegree
self.VDegree = vdegree
self._weights = weights
self.bSplineSurface = NURBSBSpline.Surface()
self.bSplineCurve.weights = weights
self.bSplineSurface.ctrlpoints = poles
self.bSplineSurface.degree_u = udegree
self.bSplineSurface.degree_v = vdegree
self.bSplineSurface.knotvector_u = self._uknotsExploded
self.bSplineSurface.knotvector_v = self._vknotsExploded
return self
def value(self, u, v):
if (self.bSplineSurface):
return Vector(self.bSplineSurface.evaluate(u, v))
else:
return None
def interpolate(self, points, periodic=False):
knotvector_u_len = len(points)
knotvector_v_len =len(points[0])
pointsConv = []
for row in points:
for col in row:
pointsConv.append((col.x, col.y, col.z))
self.bSplineSurface = fitting.interpolate_surface(pointsConv, knotvector_u_len, knotvector_v_len, self.UDegree, self.VDegree)
if (self.bSplineSurface.rational):
self._weights = self.bSplineSurface.weights
poles_tmp = reshape(self.bSplineSurface.ctrlpts, knotvector_v_len)
self._poles = []
for pole_row in poles_tmp:
self._poles.append([])
for pole_col in pole_row:
self._poles[-1].append(Vector(pole_col[0], pole_col[1], pole_col[2]))
self._uknotsExploded = self.bSplineSurface.knotvector_u
self.UKnotSequence = []
nbUKnots = len(self._uknotsExploded)
if nbUKnots > 0:
if nbUKnots == 1:
self.UKnotSequence = self._uknotsExploded
else:
self.UKnotSequence.append(self._uknotsExploded[0])
i = 1
while i < nbUKnots:
while (i < nbUKnots and isclose(self._uknotsExploded[i - 1], self._uknotsExploded[i])):
i += 1
if (i < nbUKnots):
self.UKnotSequence.append(self._uknotsExploded[i])
i += 1
self._vknotsExploded = self.bSplineSurface.knotvector_v
self.VKnotSequence = []
nbVKnots = len(self._vknotsExploded)
if nbVKnots > 0:
if nbVKnots == 1:
self.VKnotSequence = self._vknotsExploded
else:
self.VKnotSequence.append(self._vknotsExploded[0])
i = 1
while i < nbVKnots:
while (i < nbVKnots and isclose(self._vknotsExploded[i - 1], self._vknotsExploded[i])):
i += 1
if (i < nbVKnots):
self.VKnotSequence.append(self._vknotsExploded[i])
i += 1
#self._closed = periodic
# non si sa mai
self.UDegree = self.bSplineSurface.degree_u
self.VDegree = self.bSplineSurface.degree_v
from inventorloader.
By fixing all the data format issues and continuing, another error shows up:
'SurfaceSpline' object has no attribute 'entity' in:
def getSurface(self): return None if (self._surface is None) else self._surface.entity
maybe more defensive checks are needed?
Thanks.
from inventorloader.
For the record: building nubs/nurbs is quite straightforward with NURBS-python or splipy (I'd discourage scipy/numpy as being too big only for that task). With those, you can as well interopolate b-splines from points, in the same way as you already do with Part (which we don't want to kick in in Acis2Step.py).
from inventorloader.
@HolographicPrince : this is the reason why numpy was banned a "long time" ago.
@marcocecchiscmgroup : mea culpa - but is there a way to build a helical curve/surface in STEP without using Part.BSpline?
from inventorloader.
For the record: building nubs/nurbs is quite straightforward with NURBS-python or splipy (...). With those, you can as well interopolate b-splines from points, in the same way as you already do with Part (...).
As long splines have a nubs/nurbs information no problem. It's all about parametric splines (like helical surfaces) for those I have to create a model based on Part.
from inventorloader.
As long splines have a nubs/nurbs information no problem. It's all about parametric splines (like helical surfaces) for those I have to create a model based on Part.
I see.
Let's start with the helix. Here you have written a Helix class of your own, without using the Part.Helix (that would have been available, in case). So you're using Part only to do this:
self.rotateShape(helix, DIR_X, VEC(self.dirMajor.x, self.dirMajor.y, 0), DIR_Z)
self.rotateShape(helix, DIR_Z, self.vecAxis, DIR_X)
helix.translate(self.posCenter)
So this can be dealt with quite easily: just transform each single point before creating the spline. Or else, you can transform the control points, as the knots are invariant for rigid transformations.
from inventorloader.
@marcocecchiscmgroup : poles_tmp = reshape(self.bSplineSurface.ctrlpts, knotvector_v_len)
<- Is reshape from numpy?
from inventorloader.
A couple of years ago I gave you this to remove the numpy dependency, maybe you wiped it out completely:
def reshape(v, size):
if size == 1: return v
return [[v[size * i + j] for j in range(size)] for i in range(len(v) // size)]
from inventorloader.
I was only too long away from this project.
from inventorloader.
Related Issues (20)
- Error loading DSM's sab files HOT 3
- Crash loading .f3d SIGSEGV HOT 1
- Ever considered making acis2step functionality as a standalone python module/package? HOT 8
- Wrong import .sat file HOT 6
- Cannot import anymore because of 'Shape' object has no attribute 'reverse error HOT 4
- Demo-Status-0.4.2.ipt broken with STRATEGY_STEP HOT 4
- Face.build() failing to determine the correct face HOT 13
- GFA hanging forever HOT 4
- Helix not STEP converted correctly HOT 2
- Fusion360 import does not fullfill the timeline HOT 1
- Failure to build swept surface along a closed spline HOT 3
- ACIS R7 inconsistent? HOT 2
- Request to implement Fusion 360 T-splines HOT 1
- Python errors when importing .ipt file HOT 4
- exact_int_curve is not handled? HOT 2
- Access violation when importing ipt as step file. HOT 2
- Incomplete import on plain SAT
- Ipt to Step is not working. HOT 5
- FreeCAD 0.21.2 Linux x86_64 segfaults when trying to import Fusion 360 model
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from inventorloader.