From 103321cff74143f071f150cc0f644167ab30446a Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Sat, 15 Feb 2014 19:21:07 +0100 Subject: [PATCH] Use Part::Mirroing in importCSG --- src/Mod/OpenSCAD/OpenSCADUtils.py | 39 ++++++++++++++++++++++++++++ src/Mod/OpenSCAD/expandplacements.py | 7 +++++ src/Mod/OpenSCAD/importCSG.py | 9 +++++++ 3 files changed, 55 insertions(+) diff --git a/src/Mod/OpenSCAD/OpenSCADUtils.py b/src/Mod/OpenSCAD/OpenSCADUtils.py index 3e42e7374072..064da9effb90 100644 --- a/src/Mod/OpenSCAD/OpenSCADUtils.py +++ b/src/Mod/OpenSCAD/OpenSCADUtils.py @@ -195,10 +195,49 @@ def detsubmatrix(s): def isspecialorthogonalpython(submat,precision=4): return isorthogonal(submat,precision) and round(detsubmatrix(submat),precision)==1 +def isrotoinversionpython(submat,precision=4): + return isorthogonal(submat,precision) and round(detsubmatrix(submat),precision)==-1 + def isspecialorthogonal(mat,precision=4): return abs(mat.submatrix(3).isOrthogonal(10**(-precision))-1.0) < 10**(-precision) and \ abs(mat.submatrix(3).determinant()-1.0) < 10**(-precision) +def decomposerotoinversion(m,precision=4): + import FreeCAD + rmat = [[round(f,precision) for f in line] for line in fcsubmatrix(m)] + cmat = FreeCAD.Matrix() + if rmat ==[[-1,0,0],[0,1,0],[0,0,1]]: + cmat.scale(-1,1,1) + return m*cmat,FreeCAD.Vector(1) + elif rmat ==[[1,0,0],[0,-1,0],[0,0,1]]: + cmat.scale(1,-1,1) + return m*cmat, FreeCAD.Vector(0,1) + elif rmat ==[[1,0,0],[0,1,0],[0,0,-1]]: + cmat.scale(1,1,-1) + return m*cmat, FreeCAD.Vector(0,0,1) + else: + cmat.scale(1,1,-1) + return m*cmat, FreeCAD.Vector(0,0,1) + +def mirror2mat(nv,bv): + import FreeCAD + """calculate the transformation matrix of a mirror feature""" + mbef=FreeCAD.Matrix() + mbef.move(bv * -1) + maft=FreeCAD.Matrix() + maft.move(bv) + return maft*vec2householder(nv)*mbef + +def vec2householder(nv): + """calculated the householder matrix for a given normal vector""" + import FreeCAD + lnv=nv.dot(nv) + l=2/lnv if lnv > 0 else 0 + hh=FreeCAD.Matrix(nv.x*nv.x*l,nv.x*nv.y*l,nv.x*nv.z*l,0,\ + nv.y*nv.x*l,nv.y*nv.y*l,nv.y*nv.z*l,0,\ + nv.z*nv.x*l,nv.z*nv.y*l,nv.z*nv.z*l,0,0,0,0,0) + return FreeCAD.Matrix()-hh + def callopenscadmeshstring(scadstr): """Call OpenSCAD and return the result as a Mesh""" import Mesh,os diff --git a/src/Mod/OpenSCAD/expandplacements.py b/src/Mod/OpenSCAD/expandplacements.py index a3229fc8bddc..2db0b6b2abfd 100644 --- a/src/Mod/OpenSCAD/expandplacements.py +++ b/src/Mod/OpenSCAD/expandplacements.py @@ -96,6 +96,13 @@ def expandplacements(obj,placement): expandplacementsmatrix(obj,placement.toMatrix()) elif likeprimitive(obj,False): obj.Placement=ownplacement + elif obj.isDerivedFrom('Part::Mirroring'): + import OpenSCADUtils + mm = OpenSCADUtils.mirror2mat(obj.Normal,obj.Base) + #todo: set the base to 0,0,0 + innerp=FreeCAD.Placement(mm * ownplacement.toMatrix() *mm) + expandplacements(obj.Source,innerp) + obj.Placement=FreeCAD.Placement() else: for outobj in obj.OutList: if obj.isDerivedFrom('Part::Extrusion'): diff --git a/src/Mod/OpenSCAD/importCSG.py b/src/Mod/OpenSCAD/importCSG.py index 8964d74a19c4..73af7b02d493 100644 --- a/src/Mod/OpenSCAD/importCSG.py +++ b/src/Mod/OpenSCAD/importCSG.py @@ -730,6 +730,15 @@ def p_multmatrix_action(p): if printverbose: print "Orthogonal" part.Placement=FreeCAD.Placement(transform_matrix).multiply(part.Placement) new_part = part + elif isrotoinversionpython(fcsubmatrix(transform_matrix)): + cmat,axisvec = decomposerotoinversion(transform_matrix) + new_part=doc.addObject("Part::Mirroring",'mirr_%s'%part.Name) + new_part.Source=part + new_part.Normal=axisvec + new_part.Placement=FreeCAD.Placement(cmat) + new_part.Label="mirrored %s" % part.Label + if gui: + part.ViewObject.hide() elif FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/OpenSCAD").\ GetBool('useMultmatrixFeature'): from OpenSCADFeatures import MatrixTransform