FreeCAD/src/Mod/OpenSCAD/expandplacements.py
2014-02-20 11:12:51 -03:00

117 lines
5.8 KiB
Python

#***************************************************************************
#* *
#* Copyright (c) 2012 Sebastian Hoogen <github@sebastianhoogen.de> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="FreeCAD OpenSCAD Workbench - expand placements and matrices fuctions"
__author__ = "Sebastian Hoogen"
__url__ = ["http://www.freecadweb.org"]
'''
This Script includes python functions to shift all placements down the
feature tree to the most baisc objects
'''
import FreeCAD
from OpenSCADFeatures import *
from OpenSCADUtils import isspecialorthogonalpython,isspecialorthogonal
import replaceobj
def likeprimitive(obj,extrusion=False):
'''we can't push the matrix transformation further down'''
return not obj.OutList or obj.isDerivedFrom('Part::Extrusion')\
or extrusion and (obj.isDerivedFrom('Part::Revolution') \
or obj.isDerivedFrom('Part::FeaturePython')) or \
not obj.isDerivedFrom('Part::Feature')
def expandplacementsmatrix(obj,matrix):
'''expand afine transformation down the feature tree'''
ownmatrix=matrix.multiply(obj.Placement.toMatrix())
if obj.isDerivedFrom('Part::Feature') and \
isinstance(obj.Proxy,MatrixTransform):
innermatrix=ownmatrix.multiply(obj.Matrix)
if likeprimitive(obj.Base,True): #this matrix is needed
obj.Placement=FreeCAD.Placement()
obj.Matrix = innermatrix
else: #the inner object is not a primitive
expandplacementsmatrix(obj.Base,innermatrix)
#remove the matrix object
for parent in obj.Base.InList:
replaceobj.replaceobj(parent,obj,obj.Base)
out.Document.removeObject(obj.Name)
elif likeprimitive(obj,True):
#if isspecialorthogonalpython(fcsubmatrix(ownmatrix)):
if isspecialorthogonal(ownmatrix):
obj.Placement=FreeCAD.Placement()
#this should never happen unless matrices cancel out
obj.Placement=FreeCAD.Placement(ownmatrix)
else:
newobj=doc.addObject("Part::FeaturePython",'exp_trans')
MatrixTransform(newobj,ownmatrix,obj) #This object is not mutable GUI
ViewProviderTree(newobj.ViewObject)
for parent in obj.InList:
replaceobj.replaceobj(parent,obj,newobj) # register the new object in the feature tree
obj.Placement=FreeCAD.Placement()
else: #not a primitive
for outobj in obj.OutList:
if outobj.isDerivedFrom('Part::Feature') and \
isinstance(obj.Proxy,MatrixTransform):
newmatrix = ownmatrix.multiply(obj.Matrix).multiply(\
outobj.Base.Placement.toMatrix())
if likeprimitive(outobj.Base,True): #child of is like primtitive
outobj.Matrix = newmatrix
outobj.Base.Placement=FreeCAD.Placement()
else: #remove the MatrixTranformation
plainobj=outobj.Base
for parent in outobj.InList:
replaceobj.replaceobj(parent,outobj,plainobj)
outobj.Document.removeObject(outobj.Name)
expandplacementsmatrix(outobj,newmatrix)
else:
expandplacementsmatrix(outobj,ownmatrix)
obj.Placement=FreeCAD.Placement()
def expandplacements(obj,placement):
ownplacement=placement.multiply(obj.Placement)
if obj.isDerivedFrom('Part::FeaturePython') and isinstance(obj.Proxy,MatrixTransform):
#expandplacementsmatrix(obj,ownplacement.toMatrix())
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'):
obj.Dir=ownplacement.Rotation.multVec(obj.Dir)
elif obj.isDerivedFrom('Part::Revolution'):
obj.Axis=ownplacement.Rotation.multVec(obj.Axis)
#obj.Base=ownplacement.Rotation.multVec(obj.Base)
expandplacements(outobj,ownplacement)
obj.Placement=FreeCAD.Placement()
#expandplacements(rootobj,FreeCAD.Placement())