]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_STEPImportXCAF.cpp
Salome HOME
Fixed issue #20475
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_STEPImportXCAF.cpp
1 // Copyright (C) 2014-2020  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <GeomAlgoAPI_STEPImportXCAF.h>
21
22 #include <BRep_Builder.hxx>
23
24 #include <Interface_EntityIterator.hxx>
25 #include <Interface_Graph.hxx>
26 #include <Interface_InterfaceModel.hxx>
27
28 #include <Quantity_Color.hxx>
29
30 #include <StepRepr_DescriptiveRepresentationItem.hxx>
31 #include <StepRepr_ProductDefinitionShape.hxx>
32 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
33 #include <StepRepr_Representation.hxx>
34
35 #include <TDataStd_Name.hxx>
36 #include <TDF_ChildIDIterator.hxx>
37 #include <TDocStd_Document.hxx>
38 #include <TopExp.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopoDS.hxx>
41 #include <Transfer_TransientProcess.hxx>
42 #include <TransferBRep.hxx>
43
44 #include <XCAFApp_Application.hxx>
45 #include <XCAFDoc_DocumentTool.hxx>
46 #include <XCAFDoc_Location.hxx>
47 #include <XCAFDoc_ShapeTool.hxx>
48 #include <XSControl_TransferReader.hxx>
49 #include <XSControl_WorkSession.hxx>
50
51 #include <Locale_Convert.h>
52
53 //=============================================================================
54 TopoDS_Shape getShape(const Handle(Standard_Transient) &theEnti,
55                       const Handle(Transfer_TransientProcess) &theTP)
56 {
57   TopoDS_Shape aResult;
58   Handle(Transfer_Binder) aBinder = theTP->Find(theEnti);
59
60   if (aBinder.IsNull()) {
61     return aResult;
62   }
63
64   aResult = TransferBRep::ShapeResult(aBinder);
65
66   return aResult;
67 }
68
69 //=============================================================================
70 std::shared_ptr<GeomAPI_Shape> readAttributes(STEPCAFControl_Reader &theReader,
71                                std::shared_ptr<ModelAPI_ResultBody> theResultBody,
72                                const bool  theIsMaterials,
73                                std::map< std::wstring,std::list<std::wstring>> &theMaterialShape,
74                                std::string& theError)
75 {
76   // dummy XCAF Application to handle the STEP XCAF Document
77   Handle(XCAFApp_Application) dummy_app = XCAFApp_Application::GetApplication();
78   // XCAF Document to contain the STEP/IGES file itself
79   Handle(TDocStd_Document) adoc;
80
81   dummy_app->NewDocument( TCollection_ExtendedString("MDTV-CAF"), adoc);
82   // transfer STEP/IGES into the document, and get the main label
83   theReader.Transfer(adoc);
84   TDF_Label mainLabel = adoc->Main();
85   Handle_XCAFDoc_ShapeTool shapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel);
86   Handle_XCAFDoc_ColorTool colorTool = XCAFDoc_DocumentTool::ColorTool(mainLabel);
87   Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_DocumentTool::MaterialTool(mainLabel);
88   // traverse the labels recursively to set attributes on shapes
89   setShapeAttributes(shapeTool, colorTool, materialTool, mainLabel,
90                      TopLoc_Location(),theResultBody,theMaterialShape,false);
91
92   std::shared_ptr<GeomAPI_Shape> ageom =  setgeom(shapeTool,mainLabel,theError);
93
94   STEPControl_Reader aReader = theReader.ChangeReader();
95
96   // BEGIN: reading materials of sub-shapes from file
97   if ( theIsMaterials )
98   {
99     TopTools_IndexedMapOfShape anIndices;
100     TopExp::MapShapes(ageom->impl<TopoDS_Shape>(), anIndices);
101
102     Handle(Interface_InterfaceModel) Model = aReader.WS()->Model();
103     Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader();
104     if (!TR.IsNull()) {
105       Handle(Transfer_TransientProcess) TP = TR->TransientProcess();
106
107       Standard_Integer nb = Model->NbEntities();
108
109       for (Standard_Integer ie = 1; ie <= nb; ie++) {
110         Handle(Standard_Transient) enti = Model->Value(ie);
111
112         // Store materials.
113         storeMaterial(theResultBody,enti, anIndices, TP, mainLabel,theMaterialShape);
114       }
115     }
116   }
117   if (adoc->CanClose() == CDM_CCS_OK)
118     adoc->Close();
119   return ageom;
120 }
121
122 //=============================================================================
123 std::shared_ptr<GeomAPI_Shape> setgeom(const Handle(XCAFDoc_ShapeTool) &theShapeTool,
124                                        const TDF_Label &theLabel,
125                                        std::string& theError)
126 {
127   BRep_Builder aB;
128   TopoDS_Compound aCompound;
129   aB.MakeCompound(aCompound);
130
131   TDF_LabelSequence aFrshapes;
132   theShapeTool->GetShapes(aFrshapes);
133
134   std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
135
136   if (aFrshapes.Length() == 0) {
137       aGeomShape->setImpl(new TopoDS_Shape());
138       return aGeomShape;
139   } else if (aFrshapes.Length() == 1) {
140     TopoDS_Shape shape = theShapeTool->GetShape(aFrshapes.Value(1));
141     aGeomShape->setImpl(new TopoDS_Shape(shape));
142     return aGeomShape;
143   } else {
144     for (Standard_Integer i=1; i<aFrshapes.Length(); i++) {
145       TopoDS_Shape aS = theShapeTool->GetShape(aFrshapes.Value(i));
146       TDF_Label aLabel = theShapeTool->FindShape(aS, Standard_False);
147       if ( (!aLabel.IsNull()) && (theShapeTool->IsShape(aLabel)) ) {
148         if (theShapeTool->IsFree(aLabel) ) {
149           if (aS.IsNull()) {
150             continue;
151           } else {
152             if (!theShapeTool->IsReference(aLabel) ){
153               for(TDF_ChildIterator anIt(aLabel); anIt.More(); anIt.Next()) {
154                 aB.Add(aCompound, theShapeTool->GetShape(anIt.Value()) );
155               }
156             } else {
157               aB.Add(aCompound, aS);
158             }
159           }
160         }
161       }
162     }
163
164     TopoDS_Shape aShape = aCompound;
165     // Check if any BRep entity has been read, there must be at least a vertex
166     if ( !TopExp_Explorer( aShape, TopAbs_VERTEX ).More() )
167     {
168       theError = "No geometrical data in the imported file.";
169       std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
170       aGeomShape->setImpl(new TopoDS_Shape());
171       return aGeomShape;
172     }
173
174     aGeomShape->setImpl(new TopoDS_Shape(aShape));
175     return aGeomShape;
176   }
177 }
178 //=============================================================================
179 void setShapeAttributes(const Handle(XCAFDoc_ShapeTool) &theShapeTool,
180                         const Handle(XCAFDoc_ColorTool) &theColorTool,
181                         const Handle(XCAFDoc_MaterialTool) &theMaterialTool,
182                         const TDF_Label &theLabel,
183                         const TopLoc_Location &theLoc,
184                         std::shared_ptr<ModelAPI_ResultBody> theResultBody,
185                         std::map< std::wstring,std::list<std::wstring>> &theMaterialShape,
186                         bool theIsRef)
187 {
188   std::wstring aShapeName;
189   Handle(TDataStd_Name) aN;
190
191   if (theLabel.FindAttribute(TDataStd_Name::GetID(), aN)) {
192     TCollection_ExtendedString aName = aN->Get();
193
194     aShapeName =  Locale::Convert::toWString(TCollection_AsciiString(aName).ToCString()) ;
195   }
196
197   TopLoc_Location aPartLoc = theLoc;
198   Handle(XCAFDoc_Location) al;
199   if (theLabel.FindAttribute(XCAFDoc_Location::GetID(), al)) {
200     if (theIsRef)
201       aPartLoc = aPartLoc * al->Get();
202     else
203       aPartLoc = al->Get();
204   }
205
206   TDF_Label aRef;
207   if (theShapeTool->IsReference(theLabel) && theShapeTool->GetReferredShape(theLabel, aRef)) {
208
209     setShapeAttributes( theShapeTool, theColorTool, theMaterialTool, aRef,
210                         aPartLoc,theResultBody,theMaterialShape,true);
211   }
212
213   if (theShapeTool->IsSimpleShape(theLabel) && (theIsRef || theShapeTool->IsFree(theLabel))) {
214
215     TopoDS_Shape aShape = theShapeTool->GetShape(theLabel);
216
217     std::shared_ptr<GeomAPI_Shape> aShapeGeom(new GeomAPI_Shape);
218     if (!theLoc.IsIdentity()){
219         aShape.Move(theLoc);
220     }
221     aShapeGeom->setImpl(new TopoDS_Shape(aShape));
222     aShapeName = theResultBody->addShapeName(aShapeGeom, aShapeName);
223
224
225     aShape.Location(theIsRef ? theLoc : aPartLoc);
226     int aDim =
227       (aShape.ShapeType() == TopAbs_VERTEX) ?
228         0 :
229         (aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) ?
230         1 :
231         (aShape.ShapeType() == TopAbs_FACE ||
232          aShape.ShapeType() == TopAbs_SHELL) ? 2 :3;
233
234     Handle(TCollection_HAsciiString) aMatName;
235     Handle(TCollection_HAsciiString) aMatDescription;
236     Standard_Real aMatDensity;
237     Handle(TCollection_HAsciiString) aMatDensName;
238     Handle(TCollection_HAsciiString) aMatDensValType;
239
240     if (theMaterialTool->GetMaterial(theLabel, aMatName, aMatDescription, aMatDensity,
241                                  aMatDensName, aMatDensValType)) {
242       std::wstring aNameMaterial = Locale::Convert::toWString(aMatName->ToCString());
243
244       theMaterialShape[aNameMaterial].push_back(aShapeName);
245     }
246
247     Quantity_Color aCol;
248     if (theColorTool->GetColor(theLabel, XCAFDoc_ColorGen, aCol)) {
249       double r = aCol.Red(), g = aCol.Green(), b = aCol.Blue();
250       std::vector<int> ColRGB = {int(r*255),int(g*255),int(b*255)};
251       theResultBody->addShapeColor(aShapeName, ColRGB);
252     } else if (theColorTool->GetColor(theLabel, XCAFDoc_ColorSurf, aCol)) {
253       double r = aCol.Red(), g = aCol.Green(), b = aCol.Blue();
254       std::vector<int> aColRGB = {int(r*255),int(g*255),int(b*255)};
255       theResultBody->addShapeColor(aShapeName, aColRGB);
256     } else if (theColorTool->GetColor(theLabel, XCAFDoc_ColorCurv, aCol)) {
257      double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue();
258      std::vector<int> aColRGB = {int(aR*255),int(aG*255),int(aB*255)};
259       theResultBody->addShapeColor(aShapeName, aColRGB);
260     }
261     // check explicit coloring of boundary entities
262     if (aDim == 3) {
263       TopExp_Explorer aXp2(aShape, TopAbs_FACE);
264       while(aXp2.More()) {
265         if (theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorGen, aCol) ||
266            theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorSurf, aCol) ||
267            theColorTool->GetColor(aXp2.Current(), XCAFDoc_ColorCurv, aCol)) {
268           double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue();
269           TopoDS_Face aFace = TopoDS::Face(aXp2.Current());
270           std::vector<int> aColRGB = {int(aR*255),int(aG*255),int(aB*255)};
271           std::wstringstream aNameFace;
272           TopoDS_Shape aShapeface = aXp2.Current();
273           if (!theLoc.IsIdentity()){
274                   aShapeface.Move(theLoc);
275           }
276           aShapeGeom->setImpl(new TopoDS_Shape(aShapeface));
277           theResultBody->addShapeColor(
278           theResultBody->addShapeName(aShapeGeom , aNameFace.str()), aColRGB);
279         }
280         aXp2.Next();
281       }
282     }
283     if (aDim == 2) {
284       TopExp_Explorer aXp1(aShape, TopAbs_EDGE);
285       while(aXp1.More()) {
286         if (theColorTool->GetColor(aXp1.Current(), XCAFDoc_ColorGen, aCol) ||
287            theColorTool->GetColor(aXp1.Current(), XCAFDoc_ColorSurf, aCol) ||
288            theColorTool->GetColor(aXp1.Current(), XCAFDoc_ColorCurv, aCol)) {
289            double aR = aCol.Red(), aG = aCol.Green(), aB = aCol.Blue();
290            std::vector<int> aColRGB = {int(aR*255),int(aG*255),int(aB*255)};
291            std::wstringstream aNameEdge;
292            aNameEdge << L"Edge_"<< aShapeName;
293            aShapeGeom->setImpl(new TopoDS_Shape(aXp1.Current() ));
294            theResultBody->addShapeColor(
295            theResultBody->addShapeName(aShapeGeom , aNameEdge.str()), aColRGB);
296         }
297         aXp1.Next();
298       }
299     }
300   } else {
301     if (!theShapeTool->IsReference(theLabel) ){
302       TopoDS_Shape aShape = theShapeTool->GetShape(theLabel);
303
304       std::shared_ptr<GeomAPI_Shape> aShapeGeom(new GeomAPI_Shape);
305       if (!theLoc.IsIdentity()){
306           aShape.Move(theLoc);
307       }
308       aShapeGeom->setImpl(new TopoDS_Shape(aShape));
309       aShapeName = theResultBody->addShapeName(aShapeGeom, aShapeName);
310     }
311     for(TDF_ChildIterator anIt(theLabel); anIt.More(); anIt.Next()) {
312
313       setShapeAttributes( theShapeTool, theColorTool, theMaterialTool,
314                          anIt.Value(), aPartLoc,theResultBody,theMaterialShape, theIsRef);
315     }
316   }
317 }
318
319 //=============================================================================
320 void storeMaterial( std::shared_ptr<ModelAPI_ResultBody>    theResultBody,
321                     const Handle(Standard_Transient)        &theEnti,
322                     const TopTools_IndexedMapOfShape        &theIndices,
323                     const Handle(Transfer_TransientProcess) &theTP,
324                     const TDF_Label                         &theShapeLabel,
325                     std::map< std::wstring, std::list<std::wstring>> &theMaterialShape )
326 {
327   // Treat Product Definition Shape only.
328   Handle(StepRepr_ProductDefinitionShape) aPDS =
329     Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti);
330   Handle(StepBasic_ProductDefinition)     aProdDef;
331
332   if (!aPDS.IsNull()) {
333     // Product Definition Shape ==> Product Definition
334     aProdDef = aPDS->Definition().ProductDefinition();
335   }
336
337   if (!aProdDef.IsNull()) {
338     // Product Definition ==> Property Definition
339     const Interface_Graph    &aGraph = theTP->Graph();
340     Interface_EntityIterator  aSubs  = aGraph.Sharings(aProdDef);
341     TopoDS_Shape              aShape;
342
343     for(aSubs.Start(); aSubs.More(); aSubs.Next()) {
344       Handle(StepRepr_PropertyDefinition) aPropD =
345         Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value());
346
347       if (!aPropD.IsNull()) {
348         // Property Definition ==> Representation.
349         Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD);
350
351         for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) {
352           Handle(StepRepr_PropertyDefinitionRepresentation) aPDR =
353             Handle(StepRepr_PropertyDefinitionRepresentation)::
354             DownCast(aSubs1.Value());
355
356           if (!aPDR.IsNull()) {
357             // Property Definition ==> Material Name.
358             Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation();
359
360             if (!aRepr.IsNull()) {
361               Standard_Integer anIr;
362
363               for(anIr = 1; anIr <= aRepr->NbItems(); anIr++) {
364                 Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(anIr);
365                 Handle(StepRepr_DescriptiveRepresentationItem) aDRI =
366                   Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI);
367
368                 if (!aDRI.IsNull()) {
369                   // Get shape from Product Definition
370                   Handle(TCollection_HAsciiString) aMatName = aDRI->Name();
371                   if (!aMatName.IsNull()) {
372                     TCollection_ExtendedString
373                       aMatNameExt (aMatName->ToCString());
374
375                     if (aShape.IsNull()) {
376                       //Get the shape.
377                       aShape = getShape(aProdDef, theTP);
378                       if (aShape.IsNull()) {
379                         return;
380                       }
381                     }
382
383                     // as PRODUCT can be included in the main shape
384                     // several times, we look here for all iclusions.
385                     Standard_Integer anISub, aNbSubs = theIndices.Extent();
386
387                     for (anISub = 1; anISub <= aNbSubs; anISub++) {
388                       TopoDS_Shape aSub = theIndices.FindKey(anISub);
389
390                       if (aSub.IsPartner(aShape)) {
391                         std::shared_ptr<GeomAPI_Shape> aShapeGeom(new GeomAPI_Shape);
392                         aShapeGeom->setImpl(new TopoDS_Shape(aSub));
393                         std::wstring aNom = theResultBody->findShapeName(aShapeGeom);
394                         std::wstring aMName= Locale::Convert::toWString(aMatName->ToCString());
395                         theMaterialShape[aMName].push_back(aNom);
396
397                       }
398                     }
399                   }
400                 }
401               }
402             }
403           }
404         }
405       }
406     }
407   }
408 }
409