BIM: Improve onChanged Placement code
* Switched Component code to new Comp=True version of code. * Made the Placement code in both files identical. This also solves that Rotating a BuildingPart was not propagated to children.
This commit is contained in:
@@ -258,6 +258,8 @@ class BuildingPart(ArchIFC.IfcProduct):
|
||||
|
||||
def onChanged(self,obj,prop):
|
||||
|
||||
import math
|
||||
|
||||
ArchIFC.IfcProduct.onChanged(self, obj, prop)
|
||||
|
||||
# clean svg cache if needed
|
||||
@@ -269,33 +271,21 @@ class BuildingPart(ArchIFC.IfcProduct):
|
||||
self.touchChildren(obj)
|
||||
|
||||
elif prop == "Placement":
|
||||
if hasattr(self,"oldPlacement"):
|
||||
if self.oldPlacement and (self.oldPlacement != obj.Placement):
|
||||
deltap = obj.Placement.Base.sub(self.oldPlacement.Base)
|
||||
if deltap.Length == 0:
|
||||
deltap = None
|
||||
v = FreeCAD.Vector(0,0,1)
|
||||
deltar = FreeCAD.Rotation(self.oldPlacement.Rotation.multVec(v),obj.Placement.Rotation.multVec(v))
|
||||
#print "Rotation",deltar.Axis,deltar.Angle
|
||||
if deltar.Angle < 0.0001:
|
||||
deltar = None
|
||||
for child in self.getMovableChildren(obj):
|
||||
#print "moving ",child.Label
|
||||
if deltar:
|
||||
#child.Placement.Rotation = child.Placement.Rotation.multiply(deltar) - not enough, child must also move
|
||||
# use shape methods to obtain a correct placement
|
||||
import Part
|
||||
import math
|
||||
shape = Part.Shape()
|
||||
shape.Placement = child.Placement
|
||||
#print("angle before rotation:",shape.Placement.Rotation.Angle)
|
||||
#print("rotation angle:",math.degrees(deltar.Angle))
|
||||
shape.rotate(DraftVecUtils.tup(obj.Placement.Base), DraftVecUtils.tup(deltar.Axis), math.degrees(deltar.Angle))
|
||||
print("angle after rotation:",shape.Placement.Rotation.Angle)
|
||||
child.Placement = shape.Placement
|
||||
if deltap:
|
||||
print("moving child",child.Label)
|
||||
child.Placement.move(deltap)
|
||||
if hasattr(self,"oldPlacement") and self.oldPlacement != obj.Placement:
|
||||
deltap = obj.Placement.Base.sub(self.oldPlacement.Base)
|
||||
if deltap.Length == 0:
|
||||
deltap = None
|
||||
deltar = obj.Placement.Rotation * self.oldPlacement.Rotation.inverted()
|
||||
if deltar.Angle < 0.0001:
|
||||
deltar = None
|
||||
for child in self.getMovableChildren(obj):
|
||||
if deltar:
|
||||
child.Placement.rotate(self.oldPlacement.Base,
|
||||
deltar.Axis,
|
||||
math.degrees(deltar.Angle),
|
||||
comp=True)
|
||||
if deltap:
|
||||
child.Placement.move(deltap)
|
||||
|
||||
def execute(self,obj):
|
||||
|
||||
|
||||
@@ -315,36 +315,27 @@ class Component(ArchIFC.IfcProduct):
|
||||
prop: string
|
||||
The name of the property that has changed.
|
||||
"""
|
||||
|
||||
import math
|
||||
|
||||
ArchIFC.IfcProduct.onChanged(self, obj, prop)
|
||||
|
||||
if prop == "Placement":
|
||||
if hasattr(self,"oldPlacement"):
|
||||
if self.oldPlacement:
|
||||
deltap = obj.Placement.Base.sub(self.oldPlacement.Base)
|
||||
if deltap.Length == 0:
|
||||
deltap = None
|
||||
deltar = obj.Placement.Rotation * self.oldPlacement.Rotation.inverted()
|
||||
if deltar.Angle < 0.0001:
|
||||
deltar = None
|
||||
for child in self.getMovableChildren(obj):
|
||||
if deltar:
|
||||
import math
|
||||
# Code for V1.0:
|
||||
# child.Placement.rotate(self.oldPlacement.Base,
|
||||
# deltar.Axis,
|
||||
# math.degrees(deltar.Angle),
|
||||
# comp=True)
|
||||
|
||||
# Workaround solution for V0.20.3 backport:
|
||||
# See: https://forum.freecad.org/viewtopic.php?p=613196#p613196
|
||||
offset_rotation = FreeCAD.Placement(FreeCAD.Vector(0, 0, 0),
|
||||
FreeCAD.Rotation(deltar.Axis, math.degrees(deltar.Angle)),
|
||||
self.oldPlacement.Base)
|
||||
child.Placement = offset_rotation * child.Placement
|
||||
# End workaround solution.
|
||||
if deltap:
|
||||
child.Placement.move(deltap)
|
||||
if hasattr(self,"oldPlacement") and self.oldPlacement != obj.Placement:
|
||||
deltap = obj.Placement.Base.sub(self.oldPlacement.Base)
|
||||
if deltap.Length == 0:
|
||||
deltap = None
|
||||
deltar = obj.Placement.Rotation * self.oldPlacement.Rotation.inverted()
|
||||
if deltar.Angle < 0.0001:
|
||||
deltar = None
|
||||
for child in self.getMovableChildren(obj):
|
||||
if deltar:
|
||||
child.Placement.rotate(self.oldPlacement.Base,
|
||||
deltar.Axis,
|
||||
math.degrees(deltar.Angle),
|
||||
comp=True)
|
||||
if deltap:
|
||||
child.Placement.move(deltap)
|
||||
|
||||
def getMovableChildren(self,obj):
|
||||
"""Find the component's children set to move with their host.
|
||||
|
||||
Reference in New Issue
Block a user