Add support of origin and datum feature
This commit is contained in:
parent
4ad32a084f
commit
d76902b215
23
assembly.py
23
assembly.py
|
@ -1,6 +1,6 @@
|
||||||
import os
|
import os
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import FreeCAD, FreeCADGui
|
import FreeCAD, FreeCADGui, Part
|
||||||
from . import utils, gui
|
from . import utils, gui
|
||||||
from .utils import logger, objName
|
from .utils import logger, objName
|
||||||
from .constraint import Constraint, cstrName
|
from .constraint import Constraint, cstrName
|
||||||
|
@ -237,7 +237,7 @@ class AsmElement(AsmBase):
|
||||||
parent.Object.cacheChildLabel()
|
parent.Object.cacheChildLabel()
|
||||||
|
|
||||||
def execute(self,_obj):
|
def execute(self,_obj):
|
||||||
self.getShape(True)
|
# self.getShape(True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def getShape(self,refresh=False):
|
def getShape(self,refresh=False):
|
||||||
|
@ -336,10 +336,11 @@ class AsmElement(AsmBase):
|
||||||
subs = [subs[1],subs[2]]
|
subs = [subs[1],subs[2]]
|
||||||
|
|
||||||
if subs[0][-1] == '.':
|
if subs[0][-1] == '.':
|
||||||
subElement = utils.deduceSelectedElement(sel.Object,subs[0])
|
if not utils.isElement((sel.Object,subs[0])):
|
||||||
if not subElement:
|
|
||||||
raise RuntimeError('no sub element (face, edge, vertex) in '
|
raise RuntimeError('no sub element (face, edge, vertex) in '
|
||||||
'{}.{}'.format(sel.Object.Name,subs[0]))
|
'{}.{}'.format(sel.Object.Name,subs[0]))
|
||||||
|
subElement = utils.deduceSelectedElement(sel.Object,subs[0])
|
||||||
|
if subElement:
|
||||||
subs[0] += subElement
|
subs[0] += subElement
|
||||||
|
|
||||||
link = Assembly.findPartGroup(sel.Object,subs[0])
|
link = Assembly.findPartGroup(sel.Object,subs[0])
|
||||||
|
@ -412,7 +413,7 @@ class AsmElement(AsmBase):
|
||||||
if not ret:
|
if not ret:
|
||||||
# If no child assembly in 'subname', simply assign the link as
|
# If no child assembly in 'subname', simply assign the link as
|
||||||
# it is, after making sure it is referencing an sub-element
|
# it is, after making sure it is referencing an sub-element
|
||||||
if not subname or subname[-1]=='.':
|
if not utils.isElement((group,subname)):
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'Element must reference a geometry element')
|
'Element must reference a geometry element')
|
||||||
else:
|
else:
|
||||||
|
@ -619,7 +620,10 @@ def getPartInfo(parent, subname):
|
||||||
# object. And obtain the shape before part's Placement by setting
|
# object. And obtain the shape before part's Placement by setting
|
||||||
# 'transform' to False
|
# 'transform' to False
|
||||||
subname = '.'.join(names[1:])
|
subname = '.'.join(names[1:])
|
||||||
shape = part.getSubObject(subname,transform=False)
|
shape = utils.getElementShape((part,subname),Part.Shape)
|
||||||
|
if not shape:
|
||||||
|
raise RuntimeError('cannot get geometry element from {}.{}'.format(
|
||||||
|
part.Name,subname))
|
||||||
pla = part.Placement
|
pla = part.Placement
|
||||||
obj = part.getLinkedObject(False)
|
obj = part.getLinkedObject(False)
|
||||||
partName = part.Name
|
partName = part.Name
|
||||||
|
@ -956,10 +960,11 @@ class AsmConstraint(AsmGroup):
|
||||||
not isTypeOf(sobj,(AsmConstraint,AsmConstraintGroup,
|
not isTypeOf(sobj,(AsmConstraint,AsmConstraintGroup,
|
||||||
AsmElement,AsmElementLink)):
|
AsmElement,AsmElementLink)):
|
||||||
# Too bad, its a full selection, let's guess the sub element
|
# Too bad, its a full selection, let's guess the sub element
|
||||||
subElement = utils.deduceSelectedElement(found.Object,sub)
|
if not utils.isElement((found.Object,sub)):
|
||||||
if not subElement:
|
|
||||||
raise RuntimeError('no sub element (face, edge, vertex) in '
|
raise RuntimeError('no sub element (face, edge, vertex) in '
|
||||||
'{}.{}'.format(found.Object.Name,sub))
|
'{}.{}'.format(found.Object.Name,sub))
|
||||||
|
subElement = utils.deduceSelectedElement(found.Object,sub)
|
||||||
|
if subElement:
|
||||||
sub += subElement
|
sub += subElement
|
||||||
|
|
||||||
elements.append((found.Object,sub))
|
elements.append((found.Object,sub))
|
||||||
|
@ -1194,7 +1199,6 @@ class Assembly(AsmGroup):
|
||||||
obj.purgeTouched()
|
obj.purgeTouched()
|
||||||
|
|
||||||
def buildShape(self):
|
def buildShape(self):
|
||||||
import Part
|
|
||||||
obj = self.Object
|
obj = self.Object
|
||||||
if obj.BuildShape == BuildShapeNone:
|
if obj.BuildShape == BuildShapeNone:
|
||||||
obj.Shape = Part.Shape()
|
obj.Shape = Part.Shape()
|
||||||
|
@ -1763,7 +1767,6 @@ class AsmWorkPlane(object):
|
||||||
obj.Proxy = self
|
obj.Proxy = self
|
||||||
|
|
||||||
def execute(self,obj):
|
def execute(self,obj):
|
||||||
import Part
|
|
||||||
if not obj.Length or not obj.Width:
|
if not obj.Length or not obj.Width:
|
||||||
raise RuntimeError('invalid workplane size')
|
raise RuntimeError('invalid workplane size')
|
||||||
obj.Shape = Part.makePlane(obj.Length,obj.Width)
|
obj.Shape = Part.makePlane(obj.Length,obj.Width)
|
||||||
|
|
97
utils.py
97
utils.py
|
@ -77,23 +77,74 @@ def deduceSelectedElement(obj,subname):
|
||||||
if count==1:
|
if count==1:
|
||||||
return 'Vertex1'
|
return 'Vertex1'
|
||||||
|
|
||||||
def getElement(obj,tp):
|
def getElementShape(obj,tp):
|
||||||
if isinstance(obj,tuple):
|
if not isinstance(obj,(tuple,list)):
|
||||||
obj = obj[0].getSubObject(obj[1])
|
shape = obj
|
||||||
if isinstance(obj,tp):
|
else:
|
||||||
return obj
|
sobj,mat,shape = obj[0].getSubObject(obj[1],2,transform=False)
|
||||||
|
if not sobj:
|
||||||
|
return
|
||||||
|
if not shape:
|
||||||
|
if sobj.TypeId == 'App::Line':
|
||||||
|
if tp not in (Part.Shape,Part.Edge):
|
||||||
|
return
|
||||||
|
shape = Part.makeLine(
|
||||||
|
FreeCAD.Vector(-1,0,0),FreeCAD.Vector(-1,0,0))
|
||||||
|
shape.transformShape(mat,False,True)
|
||||||
|
return shape
|
||||||
|
elif sobj.TypeId == 'App::Plane':
|
||||||
|
if tp not in (Part.Shape, Part.Face):
|
||||||
|
return
|
||||||
|
shape = Part.makePlane(2,2,FreeCAD.Vector(-1,-1,0))
|
||||||
|
shape.transformShape(mat,False,True)
|
||||||
|
return shape
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not isinstance(shape,Part.Shape) or shape.isNull():
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(shape,tp):
|
||||||
|
return shape
|
||||||
|
elif isinstance(shape,(Part.Vertex,Part.Edge,Part.Face)):
|
||||||
|
return
|
||||||
|
elif tp is Part.Vertex:
|
||||||
|
if len(Part.Edges):
|
||||||
|
return
|
||||||
|
v = shape.Vertexes
|
||||||
|
if len(v)==1:
|
||||||
|
return v[0]
|
||||||
|
elif tp is Part.Edge:
|
||||||
|
if len(Part.Faces):
|
||||||
|
return
|
||||||
|
e = shape.Edges
|
||||||
|
if len(e)==1:
|
||||||
|
return e[0]
|
||||||
|
elif tp is Part.Face:
|
||||||
|
f = shape.Faces
|
||||||
|
if len(f)==1:
|
||||||
|
return f[0]
|
||||||
|
|
||||||
def isElement(obj):
|
def isElement(obj):
|
||||||
if isinstance(obj,tuple):
|
if not isinstance(obj,(tuple,list)):
|
||||||
obj = obj[0].getSubObject(obj[1])
|
shape = obj
|
||||||
return isinstance(obj,Part.Vertex) or \
|
else:
|
||||||
isinstance(obj,Part.Face) or \
|
sobj,_,shape = obj[0].getSubObject(obj[1],2)
|
||||||
isinstance(obj,Part.Edge)
|
if not sobj:
|
||||||
|
return
|
||||||
|
if not shape:
|
||||||
|
return sobj.TypeId in ('App::Line','App::Plane')
|
||||||
|
if isinstance(obj,(Part.Vertex,Part.Face,Part.Edge)):
|
||||||
|
return True
|
||||||
|
if isinstance(shape,Part.Shape) and not shape.isNull():
|
||||||
|
return len(shape.Vertexes)==1 or \
|
||||||
|
len(shape.Edges)==1 or \
|
||||||
|
len(shape.Faces)==1
|
||||||
|
|
||||||
def isPlanar(obj):
|
def isPlanar(obj):
|
||||||
if isCircularEdge(obj):
|
if isCircularEdge(obj):
|
||||||
return True
|
return True
|
||||||
shape = getElement(obj,Part.Face)
|
shape = getElementShape(obj,Part.Face)
|
||||||
if not shape:
|
if not shape:
|
||||||
return False
|
return False
|
||||||
elif str(shape.Surface) == '<Plane object>':
|
elif str(shape.Surface) == '<Plane object>':
|
||||||
|
@ -108,7 +159,7 @@ def isPlanar(obj):
|
||||||
return error_normalized < 10**-6
|
return error_normalized < 10**-6
|
||||||
|
|
||||||
def isCylindricalPlane(obj):
|
def isCylindricalPlane(obj):
|
||||||
face = getElement(obj,Part.Face)
|
face = getElementShape(obj,Part.Face)
|
||||||
if not face:
|
if not face:
|
||||||
return False
|
return False
|
||||||
elif hasattr(face.Surface,'Radius'):
|
elif hasattr(face.Surface,'Radius'):
|
||||||
|
@ -123,7 +174,7 @@ def isCylindricalPlane(obj):
|
||||||
return error_normalized < 10**-6
|
return error_normalized < 10**-6
|
||||||
|
|
||||||
def isAxisOfPlane(obj):
|
def isAxisOfPlane(obj):
|
||||||
face = getElement(obj,Part.Face)
|
face = getElementShape(obj,Part.Face)
|
||||||
if not face:
|
if not face:
|
||||||
return False
|
return False
|
||||||
if str(face.Surface) == '<Plane object>':
|
if str(face.Surface) == '<Plane object>':
|
||||||
|
@ -134,7 +185,7 @@ def isAxisOfPlane(obj):
|
||||||
return error_normalized < 10**-6
|
return error_normalized < 10**-6
|
||||||
|
|
||||||
def isCircularEdge(obj):
|
def isCircularEdge(obj):
|
||||||
edge = getElement(obj,Part.Edge)
|
edge = getElementShape(obj,Part.Edge)
|
||||||
if not edge:
|
if not edge:
|
||||||
return False
|
return False
|
||||||
elif not hasattr(edge, 'Curve'): #issue 39
|
elif not hasattr(edge, 'Curve'): #issue 39
|
||||||
|
@ -156,7 +207,7 @@ def isCircularEdge(obj):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isLinearEdge(obj):
|
def isLinearEdge(obj):
|
||||||
edge = getElement(obj,Part.Edge)
|
edge = getElementShape(obj,Part.Edge)
|
||||||
if not edge:
|
if not edge:
|
||||||
return False
|
return False
|
||||||
elif not hasattr(edge, 'Curve'): #issue 39
|
elif not hasattr(edge, 'Curve'): #issue 39
|
||||||
|
@ -178,24 +229,24 @@ def isLinearEdge(obj):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isVertex(obj):
|
def isVertex(obj):
|
||||||
return getElement(obj,Part.Vertex) is not None
|
return getElementShape(obj,Part.Vertex) is not None
|
||||||
|
|
||||||
def hasCenter(obj):
|
def hasCenter(obj):
|
||||||
return isVertex(obj) or isCircularEdge(obj) or \
|
return isVertex(obj) or isCircularEdge(obj) or \
|
||||||
isAxisOfPlane(obj) or isSphericalSurface(obj)
|
isAxisOfPlane(obj) or isSphericalSurface(obj)
|
||||||
|
|
||||||
def isSphericalSurface(obj):
|
def isSphericalSurface(obj):
|
||||||
face = getElement(obj,Part.Face)
|
face = getElementShape(obj,Part.Face)
|
||||||
if not face:
|
if not face:
|
||||||
return False
|
return False
|
||||||
return str( face.Surface ).startswith('Sphere ')
|
return str( face.Surface ).startswith('Sphere ')
|
||||||
|
|
||||||
def getElementPos(obj):
|
def getElementPos(obj):
|
||||||
pos = None
|
pos = None
|
||||||
vertex = getElement(obj,Part.Vertex)
|
vertex = getElementShape(obj,Part.Vertex)
|
||||||
if vertex:
|
if vertex:
|
||||||
return vertex.Point
|
return vertex.Point
|
||||||
face = getElement(obj,Part.Face)
|
face = getElementShape(obj,Part.Face)
|
||||||
if face:
|
if face:
|
||||||
surface = face.Surface
|
surface = face.Surface
|
||||||
if str(surface) == '<Plane object>':
|
if str(surface) == '<Plane object>':
|
||||||
|
@ -217,7 +268,7 @@ def getElementPos(obj):
|
||||||
if error_normalized < 10**-6: #then good rotation_axis fix
|
if error_normalized < 10**-6: #then good rotation_axis fix
|
||||||
pos = center
|
pos = center
|
||||||
else:
|
else:
|
||||||
edge = getElement(obj,Part.Edge)
|
edge = getElementShape(obj,Part.Edge)
|
||||||
if edge:
|
if edge:
|
||||||
if isLine(edge.Curve):
|
if isLine(edge.Curve):
|
||||||
# pos = edge.Vertexes[-1].Point
|
# pos = edge.Vertexes[-1].Point
|
||||||
|
@ -244,7 +295,7 @@ def getElementPos(obj):
|
||||||
|
|
||||||
def getElementRotation(obj,reverse=False):
|
def getElementRotation(obj,reverse=False):
|
||||||
axis = None
|
axis = None
|
||||||
face = getElement(obj,Part.Face)
|
face = getElementShape(obj,Part.Face)
|
||||||
if face:
|
if face:
|
||||||
if face.Orientation == 'Reversed':
|
if face.Orientation == 'Reversed':
|
||||||
reverse = not reverse
|
reverse = not reverse
|
||||||
|
@ -265,7 +316,7 @@ def getElementRotation(obj,reverse=False):
|
||||||
if error_normalized < 10**-6: #then good rotation_axis fix
|
if error_normalized < 10**-6: #then good rotation_axis fix
|
||||||
axis = axis_fitted
|
axis = axis_fitted
|
||||||
else:
|
else:
|
||||||
edge = getElement(obj,Part.Edge)
|
edge = getElementShape(obj,Part.Edge)
|
||||||
if edge:
|
if edge:
|
||||||
if isLine(edge.Curve):
|
if isLine(edge.Curve):
|
||||||
axis = edge.Curve.tangent(0)[0]
|
axis = edge.Curve.tangent(0)[0]
|
||||||
|
@ -301,7 +352,7 @@ def getNormal(obj):
|
||||||
|
|
||||||
def getElementCircular(obj):
|
def getElementCircular(obj):
|
||||||
'return radius if it is closed, or a list of two endpoints'
|
'return radius if it is closed, or a list of two endpoints'
|
||||||
edge = getElement(obj,Part.Edge)
|
edge = getElementShape(obj,Part.Edge)
|
||||||
if not edge:
|
if not edge:
|
||||||
return
|
return
|
||||||
elif not hasattr(edge, 'Curve'): #issue 39
|
elif not hasattr(edge, 'Curve'): #issue 39
|
||||||
|
|
Loading…
Reference in New Issue
Block a user