diff --git a/constraint.py b/constraint.py index 3fe2450..787c736 100644 --- a/constraint.py +++ b/constraint.py @@ -253,7 +253,7 @@ def _c(solver,partInfo,subname,shape,requireArc=False,retAll=False): if utils.isDraftCircle(partInfo.Part): part = partInfo.Part - w,p,n = partInfo.Workplane + w,p,n,_ = partInfo.Workplane if system.sketchPlane and not solver.isFixedElement(part,subname): system.NameTag = nameTag + '.o' @@ -596,6 +596,15 @@ class Base(object): info = o.Proxy.getInfo() partInfo = solver.getPartInfo(info) ret.append(e(solver,partInfo,info.Subname,info.Shape,retAll=retAll)) + + if cls._workplane and len(elements)==len(cls._entityDef): + if solver.system.sketchPlane: + ret.append(solver.system.sketchPlane[0]) + elif int(cls._workplane)>1: + raise RuntimeError('Constraint "{}" requires a sketch plane ' + 'or a {} element to define a projection plane'.format( + cstrName(obj), _ordinal[len(elements)])) + solver.system.log('{} entities: {}'.format(cstrName(obj),ret)) return ret @@ -1030,66 +1039,57 @@ class Symmetric(Base2): _tooltip='Add a "{}" constraint to make two points symmetric about a plane.' -class UseSketchPlane(Base2): - _id = -1 - _workplane = True - - @classmethod - def getEntities(cls,obj,solver,retAll=False): - ret = super(UseSketchPlane,cls).getEntities(obj,solver,retAll) - elements = obj.Proxy.getElements() - if len(elements)==len(cls._entityDef): - if not solver.system.sketchPlane: - raise RuntimeError('Constraint "{}" requires a sketch plane ' - 'or a {} element to define a projection plane'.format( - cstrName(obj), _ordinal[len(elements)])) - ret.append(solver.system.sketchPlane[0]) - return ret - -class SymmetricHorizontal(UseSketchPlane): +class SymmetricHorizontal(Base2): _id = 17 _entityDef = (_p,_p) + _workplane = 2 -class SymmetricVertical(UseSketchPlane): +class SymmetricVertical(Base2): _id = 18 _entityDef = (_p,_p) + _workplane = 2 class SymmetricLine(Base2): _id = 19 - _entityDef = (_p,_p,_l,_w) + _entityDef = (_p,_p,_l) + _workplane = 2 _iconName = 'Assembly_ConstraintSymmetricLine.svg' _tooltip='Add a "{}" constraint to make two points symmetric about a line.' -class PointsHorizontal(UseSketchPlane): +class PointsHorizontal(Base2): _id = 21 _entityDef = (_p,_p) + _workplane = 2 _iconName = 'Assembly_ConstraintPointsHorizontal.svg' _tooltip='Add a "{}" constraint to make two points horizontal with each\n'\ 'other when projected onto a plane.' -class PointsVertical(UseSketchPlane): +class PointsVertical(Base2): _id = 22 _entityDef = (_p,_p) + _workplane = 2 _iconName = 'Assembly_ConstraintPointsVertical.svg' _tooltip='Add a "{}" constraint to make two points vertical with each\n'\ 'other when projected onto a plane.' -class LineHorizontal(UseSketchPlane): +class LineHorizontal(Base2): _id = 23 _entityDef = (_l,) + _workplane = 2 _iconName = 'Assembly_ConstraintLineHorizontal.svg' _tooltip='Add a "{}" constraint to make a line segment horizontal when\n'\ 'projected onto a plane.' -class LineVertical(UseSketchPlane): +class LineVertical(Base2): _id = 24 _entityDef = (_l,) + _workplane = 2 _iconName = 'Assembly_ConstraintLineVertical.svg' _tooltip='Add a "{}" constraint to make a line segment vertical when\n'\ 'projected onto a plane.' diff --git a/solver.py b/solver.py index d4f4daf..97e3bbc 100644 --- a/solver.py +++ b/solver.py @@ -11,9 +11,10 @@ from .system import System # PartName: text name of the part # Placement: the original placement of the part # Params: 7 parameters that defines the transformation of this part -# Workplane: a tuple of three entity handles, that is the workplane, the origin -# point, and the normal. The workplane, defined by the origin and -# norml, is essentially the XY reference plane of the part. +# Workplane: a tuple of four entity handles, that is the workplane, the origin +# point, and the normal, and x pointing normal. The workplane, +# defined by the origin and norml, is essentially the XY reference +# plane of the part. # EntityMap: string -> entity handle map, for caching # Group: transforming entity group handle PartInfo = namedtuple('SolverPartInfo', ('Part','PartName','Placement', @@ -39,10 +40,13 @@ class Solver(object): # convenience constant of zero self.v0 = self.system.addParamV(0,group=self._fixedGroup) + # convenience normals + rotx = FreeCAD.Rotation(FreeCAD.Vector(0,1,0),-90) + self.nx = self.system.addNormal3dV(*utils.getNormal(rotx)) + self._fixedParts = Constraint.getFixedParts(self,cstrs) - if self._fixedParts is None: - self.system.log('no fixed part found') - return + for part in self._fixedParts: + self._fixedElements.add((part,None)) for cstr in cstrs: self.system.log('preparing {}'.format(cstrName(cstr))) @@ -181,7 +185,8 @@ class Solver(object): return part in self._fixedParts def isFixedElement(self,part,subname): - return self.isFixedPart(part) or (part,subname) in self._fixedElements + return (part,None) in self._fixedElements or \ + (part,subname) in self._fixedElements def addFixedElement(self,part,subname): self._fixedElements.add((part,subname)) @@ -209,9 +214,12 @@ class Solver(object): p = self.system.addPoint3d(*params[:3],group=g) self.system.NameTag = info.PartName + '.n' n = self.system.addNormal3d(*params[3:],group=g) + self.system.NameTag = info.PartName + '.nx' + nx = self.system.addTransform(self.nx, + self.v0,self.v0,self.v0,*params[3:],group=g) self.system.NameTag = info.PartName + '.w' w = self.system.addWorkplane(p,n,group=g) - h = (w,p,n) + h = (w,p,n,nx) partInfo = PartInfo(Part = info.Part, PartName = info.PartName,