22
22
#* *
23
23
#***************************************************************************
24
24
25
- import FreeCAD ,Draft ,ArchCommands ,DraftVecUtils ,sys ,ArchIFC
25
+ import FreeCAD
26
+ import Draft
27
+ import ArchCommands
28
+ import DraftVecUtils
29
+ import sys
30
+ import ArchIFC
31
+ import tempfile
32
+ import os
26
33
if FreeCAD .GuiUp :
27
34
import FreeCADGui
28
35
from PySide import QtCore , QtGui
@@ -35,7 +42,6 @@ def translate(ctxt,txt):
35
42
def QT_TRANSLATE_NOOP (ctxt ,txt ):
36
43
return txt
37
44
# \endcond
38
- import sys
39
45
if sys .version_info .major >= 3 :
40
46
unicode = str
41
47
@@ -335,6 +341,9 @@ def setProperties(self,obj):
335
341
obj .addProperty ("App::PropertyString" ,"Tag" ,"Component" ,QT_TRANSLATE_NOOP ("App::Property" ,"An optional tag for this component" ))
336
342
if not "Shape" in pl :
337
343
obj .addProperty ("Part::PropertyPartShape" ,"Shape" ,"BuildingPart" ,QT_TRANSLATE_NOOP ("App::Property" ,"The shape of this object" ))
344
+ if not "SavedInventor" in pl :
345
+ obj .addProperty ("App::PropertyFileIncluded" ,"SavedInventor" ,"BuildingPart" ,QT_TRANSLATE_NOOP ("App::Property" ,"This property stores an inventor representation for this object" ))
346
+ obj .setEditorMode ("SavedInventor" ,2 )
338
347
339
348
self .Type = "BuildingPart"
340
349
@@ -368,7 +377,7 @@ def onChanged(self,obj,prop):
368
377
369
378
elif prop == "Placement" :
370
379
if hasattr (self ,"oldPlacement" ):
371
- if self .oldPlacement :
380
+ if self .oldPlacement and ( self . oldPlacement != obj . Placement ) :
372
381
deltap = obj .Placement .Base .sub (self .oldPlacement .Base )
373
382
if deltap .Length == 0 :
374
383
deltap = None
@@ -399,8 +408,14 @@ def execute(self,obj):
399
408
# gather all the child shapes into a compound
400
409
shapes = self .getShapes (obj )
401
410
if shapes :
411
+ f = []
412
+ for s in shapes :
413
+ f .extend (s .Faces )
414
+ #print("faces before compound:",len(f))
402
415
import Part
403
- obj .Shape = Part .makeCompound (shapes )
416
+ obj .Shape = Part .makeCompound (f )
417
+ #print("faces after compound:",len(obj.Shape.Faces))
418
+ #print("recomputing ",obj.Label)
404
419
obj .Area = self .getArea (obj )
405
420
406
421
def getArea (self ,obj ):
@@ -421,18 +436,9 @@ def getShapes(self,obj):
421
436
"recursively get the shapes of objects inside this BuildingPart"
422
437
423
438
shapes = []
424
- if obj .isDerivedFrom ("Part::Feature" ) and obj .Shape and (not obj .Shape .isNull ()):
425
- shapes .append (obj .Shape )
426
- if hasattr (obj ,"Group" ):
427
- for child in obj .Group :
428
- shapes .extend (self .getShapes (child ))
429
- for i in obj .InList :
430
- if hasattr (i ,"Hosts" ):
431
- if obj in i .Hosts :
432
- shapes .extend (self .getShapes (i ))
433
- elif hasattr (i ,"Host" ):
434
- if obj == i .Host :
435
- shapes .extend (self .getShapes (i ))
439
+ for child in Draft .getGroupContents (obj ):
440
+ if child .isDerivedFrom ("Part::Feature" ):
441
+ shapes .extend (child .Shape .Faces )
436
442
return shapes
437
443
438
444
def getSpaces (self ,obj ):
@@ -514,14 +520,15 @@ def setProperties(self,vobj):
514
520
vobj .ChildrenLineColor = (float ((c >> 24 )& 0xFF )/ 255.0 ,float ((c >> 16 )& 0xFF )/ 255.0 ,float ((c >> 8 )& 0xFF )/ 255.0 ,0.0 )
515
521
if not "ChildrenTransparency" in pl :
516
522
vobj .addProperty ("App::PropertyPercent" ,"ChildrenTransparency" ,"Children" ,QT_TRANSLATE_NOOP ("App::Property" ,"The transparency of child objects" ))
517
-
518
523
if not "CutView" in pl :
519
524
vobj .addProperty ("App::PropertyBool" ,"CutView" ,"Clip" ,QT_TRANSLATE_NOOP ("App::Property" ,"Cut the view above this level" ))
520
525
if not "CutMargin" in pl :
521
526
vobj .addProperty ("App::PropertyLength" ,"CutMargin" ,"Clip" ,QT_TRANSLATE_NOOP ("App::Property" ,"The distance between the level plane and the cut line" ))
522
527
vobj .CutMargin = 1600
523
528
if not "AutoCutView" in pl :
524
529
vobj .addProperty ("App::PropertyBool" ,"AutoCutView" ,"Clip" ,QT_TRANSLATE_NOOP ("App::Property" ,"Turn cutting on when activating this level" ))
530
+ if not "SaveInventor" in pl :
531
+ vobj .addProperty ("App::PropertyBool" ,"SaveInventor" ,"BuildingPart" ,QT_TRANSLATE_NOOP ("App::Property" ,"If this is enabled, the inventor representation of this object will be saved in the FreeCAD file, allowing to reference it in other file sin lightweight mode." ))
525
532
526
533
def onDocumentRestored (self ,vobj ):
527
534
@@ -591,6 +598,9 @@ def updateData(self,obj,prop):
591
598
if len (colors ) == len (obj .Shape .Faces ):
592
599
if colors != obj .ViewObject .DiffuseColor :
593
600
obj .ViewObject .DiffuseColor = colors
601
+ self .writeInventor (obj )
602
+ #else:
603
+ #print("color mismatch:",len(colors),"colors,",len(obj.Shape.Faces),"faces")
594
604
elif prop == "Group" :
595
605
self .onChanged (obj .ViewObject ,"ChildrenOverride" )
596
606
elif prop == "Label" :
@@ -601,23 +611,14 @@ def getColors(self,obj):
601
611
"recursively get the colors of objects inside this BuildingPart"
602
612
603
613
colors = []
604
- if obj .isDerivedFrom ("Part::Feature" ) and obj .Shape and (not obj .Shape .isNull ()):
605
- if hasattr (obj .ViewObject ,"DiffuseColor" ) and (len (obj .ViewObject .DiffuseColor ) == len (obj .Shape .Faces )):
606
- colors .extend (obj .ViewObject .DiffuseColor )
607
- elif hasattr (obj .ViewObject ,"ShapeColor" ):
608
- c = obj .ViewObject .ShapeColor [:3 ]+ (obj .ViewObject .Transparency / 100.0 ,)
609
- for i in range (len (obj .Shape .Faces )):
610
- colors .append (c )
611
- if hasattr (obj ,"Group" ):
612
- for child in obj .Group :
613
- colors .extend (self .getColors (child ))
614
- for i in obj .InList :
615
- if hasattr (i ,"Hosts" ):
616
- if obj in i .Hosts :
617
- colors .extend (self .getColors (i ))
618
- elif hasattr (i ,"Host" ):
619
- if obj == i .Host :
620
- colors .extend (self .getColors (i ))
614
+ for child in Draft .getGroupContents (obj ):
615
+ if child .isDerivedFrom ("Part::Feature" ):
616
+ if len (child .ViewObject .DiffuseColor ) == len (child .Shape .Faces ):
617
+ colors .extend (child .ViewObject .DiffuseColor )
618
+ else :
619
+ c = child .ViewObject .ShapeColor [:3 ]+ (child .ViewObject .Transparency / 100.0 ,)
620
+ for i in range (len (child .Shape .Faces )):
621
+ colors .append (c )
621
622
return colors
622
623
623
624
def onChanged (self ,vobj ,prop ):
@@ -728,6 +729,8 @@ def onChanged(self,vobj,prop):
728
729
# turn clipping off when turning the object off
729
730
if hasattr (vobj ,"Visibility" ) and not (vobj .Visibility ) and hasattr (vobj ,"CutView" ):
730
731
vobj .CutView = False
732
+ elif prop == "SaveInventor" :
733
+ self .writeInventor (vobj .Object )
731
734
732
735
def onDelete (self ,vobj ,subelements ):
733
736
@@ -737,6 +740,7 @@ def onDelete(self,vobj,subelements):
737
740
for o in Draft .getGroupContents (vobj .Object .Group ,walls = True ):
738
741
if hasattr (o .ViewObject ,"Lighting" ):
739
742
o .ViewObject .Lighting = "Two side"
743
+ return True
740
744
741
745
def doubleClicked (self ,vobj ):
742
746
@@ -865,5 +869,36 @@ def __getstate__(self):
865
869
def __setstate__ (self ,state ):
866
870
return None
867
871
872
+ def writeInventor (self ,obj ):
873
+
874
+ def callback (match ):
875
+ return next (callback .v )
876
+
877
+ if hasattr (obj .ViewObject ,"SaveInventor" ) and obj .ViewObject .SaveInventor :
878
+ if obj .Shape and obj .Shape .Faces and hasattr (obj ,"SavedInventor" ):
879
+ colors = obj .ViewObject .DiffuseColor
880
+ if len (colors ) != len (obj .Shape .Faces ):
881
+ print ("Debug: Colors mismatch in" ,obj .Label )
882
+ colors = None
883
+ iv = self .Object .Shape .writeInventor ()
884
+ import re
885
+ if colors :
886
+ if len (re .findall ("IndexedFaceSet" ,iv )) == len (obj .Shape .Faces ):
887
+ # convert colors to iv representations
888
+ colors = ["Material { diffuseColor " + str (color [0 ])+ " " + str (color [1 ])+ " " + str (color [2 ])+ "}\n IndexedFaceSet" for color in colors ]
889
+ # replace
890
+ callback .v = iter (colors )
891
+ iv = re .sub ("IndexedFaceSet" ,callback ,iv )
892
+ else :
893
+ print ("Debug: IndexedFaceSet mismatch in" ,obj .Label )
894
+ # save embedded file
895
+ tf = tempfile .mkstemp (prefix = obj .Name ,suffix = ".iv" )[1 ]
896
+ f = open (tf ,"w" )
897
+ f .write (iv )
898
+ f .close ()
899
+ obj .SavedInventor = tf
900
+ os .remove (tf )
901
+
902
+
868
903
if FreeCAD .GuiUp :
869
904
FreeCADGui .addCommand ('Arch_BuildingPart' ,CommandBuildingPart ())
0 commit comments