0030856: Data Exchange - Wrong colors after STEP file import
authorika <ika@opencascade.com>
Wed, 31 Jul 2019 15:09:04 +0000 (18:09 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 6 Aug 2019 14:14:42 +0000 (17:14 +0300)
Fix processing of colors, attached to assemblies in STEP file.

src/STEPCAFControl/STEPCAFControl_Reader.cxx
tests/bugs/step/bug30856 [new file with mode: 0644]

index 3aa10e2..d8d2247 100644 (file)
@@ -26,6 +26,7 @@
 #include <NCollection_DataMap.hxx>
 #include <OSD_Path.hxx>
 #include <Quantity_Color.hxx>
+#include <Quantity_ColorRGBA.hxx>
 #include <StepAP214_AppliedExternalIdentificationAssignment.hxx>
 #include <StepBasic_ConversionBasedUnitAndLengthUnit.hxx>
 #include <StepBasic_ConversionBasedUnitAndPlaneAngleUnit.hxx>
@@ -888,6 +889,45 @@ static void findStyledSR(const Handle(StepVisual_StyledItem) &style,
 
 
 //=======================================================================
+//function : propagateColorToParts
+//purpose  : auxilary, propagate color styles from assemblies to parts
+//=======================================================================
+
+static void propagateColorToParts(const Handle(XCAFDoc_ShapeTool)& theSTool,
+                                  const Handle(XCAFDoc_ColorTool)& theCTool,
+                                  const TDF_Label& theRoot)
+{
+  // collect components to propagate
+  TDF_LabelSequence aComponents;
+  if (theRoot.IsEqual(theSTool->Label()))
+    theSTool->GetFreeShapes(aComponents);
+  else
+    theSTool->GetComponents(theRoot, aComponents);
+
+  // iterate each component
+  for (TDF_LabelSequence::Iterator anIt(aComponents); anIt.More(); anIt.Next())
+  {
+    // get original label
+    TDF_Label anOriginalL = anIt.Value();
+    theSTool->GetReferredShape(anOriginalL, anOriginalL);
+
+    // propagate to components without own colors
+    TDF_Label aColorL, aDummyColorL;
+    for (Standard_Integer aType = 1; aType <= 3; aType++)
+    {
+      if (theCTool->GetColor(theRoot, (XCAFDoc_ColorType)aType, aColorL) &&
+          !theCTool->GetColor(anOriginalL, (XCAFDoc_ColorType)aType, aDummyColorL))
+        theCTool->SetColor(anOriginalL, aColorL, (XCAFDoc_ColorType)aType);
+    }
+    if (!theCTool->IsVisible(theRoot))
+      theCTool->SetVisibility(anOriginalL, Standard_False);
+
+    // propagate to next level children
+    if (theSTool->IsAssembly(anOriginalL))
+      propagateColorToParts(theSTool, theCTool, anOriginalL);
+  }
+}
+//=======================================================================
 //function : ReadColors
 //purpose  : 
 //=======================================================================
@@ -934,20 +974,20 @@ Standard_Boolean STEPCAFControl_Reader::ReadColors(const Handle(XSControl_WorkSe
     if (!Styles.GetColors(style, SurfCol, BoundCol, CurveCol, IsComponent) && IsVisible)
       continue;
 
-    // find shape
-    NCollection_Vector<Handle(Standard_Transient)> anItems;
-    if (!style->Item().IsNull()) {
-      anItems.Append(style->Item());
-    }
-    else if (!style->ItemAP242().Representation().IsNull()) {
-      //special case for AP242: item can be Reprsentation
-      Handle(StepRepr_Representation) aRepr = style->ItemAP242().Representation();
-      for (Standard_Integer j = 1; j <= aRepr->Items()->Length(); j++)
-        anItems.Append(aRepr->Items()->Value(j));
+    // collect styled items
+    NCollection_Vector<StepVisual_StyledItemTarget> anItems;
+    if (!style->ItemAP242().IsNull()) {
+      anItems.Append(style->ItemAP242());
     }
+
+    const Handle(Transfer_TransientProcess) &TP = WS->TransferReader()->TransientProcess();
     for (Standard_Integer itemIt = 0; itemIt < anItems.Length(); itemIt++) {
-      TopoDS_Shape S = STEPConstruct::FindShape(Styles.TransientProcess(),
-        Handle(StepRepr_RepresentationItem)::DownCast(anItems.Value(itemIt)));
+      Standard_Integer index = TP->MapIndex(anItems.Value(itemIt).Value());
+      TopoDS_Shape S;
+      if (index > 0) {
+        Handle(Transfer_Binder) binder = TP->MapItem(index);
+        S = TransferBRep::ShapeResult(binder);
+      }
       Standard_Boolean isSkipSHUOstyle = Standard_False;
       // take shape with real location.
       while (IsComponent) {
@@ -1051,6 +1091,9 @@ Standard_Boolean STEPCAFControl_Reader::ReadColors(const Handle(XSControl_WorkSe
     }
   }
   CTool->ReverseChainsOfTreeNodes();
+
+  // some colors can be attached to assemblies, propagate them to components
+  propagateColorToParts(STool, CTool, STool->Label());
   return Standard_True;
 }
 
diff --git a/tests/bugs/step/bug30856 b/tests/bugs/step/bug30856
new file mode 100644 (file)
index 0000000..7ba7590
--- /dev/null
@@ -0,0 +1,48 @@
+puts "========================"
+puts "0030856: Wrong colors after STEP file import"
+puts "========================"
+
+pload DCAF
+
+ReadStep D1 [locate_data_file bug30856_SOT223-4P230_700X190L65X72.step]
+WriteStep D1 $imagedir/${casename}.stp
+ReadStep D2 $imagedir/${casename}.stp
+
+# Check colors
+# Blue
+set color1 [XGetShapeColor D1 0:1:1:1:1 s]
+set color2 [XGetShapeColor D2 0:1:1:1:1 s]
+if {$color1 != "BLUE1" || $color2 != "BLUE1"} {
+  puts "Error: wrong color."
+}
+
+# Gray
+set color1 [XGetShapeColor D1 0:1:1:1:2 s]
+set color2 [XGetShapeColor D2 0:1:1:1:2 s]
+if {$color1 != "GRAY" || $color2 != "GRAY"} {
+  puts "Error: wrong color."
+}
+
+set color1 [XGetShapeColor D1 0:1:1:1:3 s]
+set color2 [XGetShapeColor D2 0:1:1:1:3 s]
+if {$color1 != "GRAY" || $color2 != "GRAY"} {
+  puts "Error: wrong color."
+}
+
+set color1 [XGetShapeColor D1 0:1:1:1:4 s]
+set color2 [XGetShapeColor D2 0:1:1:1:4 s]
+if {$color1 != "GRAY" || $color2 != "GRAY"} {
+  puts "Error: wrong color."
+}
+
+# White
+set color1 [XGetShapeColor D1 0:1:1:1:30 s]
+set color2 [XGetShapeColor D2 0:1:1:1:30 s]
+if {$color1 != "WHITE" || $color2 != "WHITE"} {
+  puts "Error: wrong color."
+}
+
+# Clean data
+Close D1
+Close D2
+file delete $imagedir/${casename}.stp