1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 //:k8 abv 6 Jan 99: unique names for PRODUCTs
15 //:k9 abv 6 Jan 99: TR10: eliminating duplicated APPLICATION_CONTEXT entities
16 //abv,gka 05.04.99: S4136: change parameters and update units
17 // PTV 22.08.2002 OCC609 transfer solo vertices into step file.
18 // PTV 16.09.2002 OCC725 transfer compound of vertices into one geometrical curve set.
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRep_TEdge.hxx>
23 #include <BRepTools_Modifier.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_Line.hxx>
26 #include <Geom_Plane.hxx>
27 #include <Geom_Surface.hxx>
28 #include <GeomToStep_MakeAxis2Placement3d.hxx>
29 #include <Interface_Macros.hxx>
30 #include <Interface_MSG.hxx>
31 #include <Interface_Static.hxx>
32 #include <Message_ProgressScope.hxx>
33 #include <ShapeAnalysis_ShapeTolerance.hxx>
34 #include <ShapeProcess_ShapeContext.hxx>
35 #include <Standard_Type.hxx>
36 #include <StepBasic_ApplicationProtocolDefinition.hxx>
37 #include <StepBasic_HArray1OfProduct.hxx>
38 #include <STEPConstruct_Assembly.hxx>
39 #include <STEPConstruct_Part.hxx>
40 #include <STEPConstruct_UnitContext.hxx>
41 #include <STEPControl_ActorWrite.hxx>
42 #include <STEPControl_StepModelType.hxx>
43 #include <StepData_GlobalFactors.hxx>
44 #include <StepData_StepModel.hxx>
45 #include <StepGeom_Axis2Placement3d.hxx>
46 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
47 #include <StepGeom_Point.hxx>
48 #include <StepRepr_ShapeRepresentationRelationship.hxx>
49 #include <StepShape_AdvancedBrepShapeRepresentation.hxx>
50 #include <StepShape_BrepWithVoids.hxx>
51 #include <StepShape_FacetedBrep.hxx>
52 #include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
53 #include <StepShape_FacetedBrepShapeRepresentation.hxx>
54 #include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
55 #include <StepShape_GeometricCurveSet.hxx>
56 #include <StepShape_GeometricSetSelect.hxx>
57 #include <StepShape_HArray1OfGeometricSetSelect.hxx>
58 #include <StepShape_ManifoldSolidBrep.hxx>
59 #include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
60 #include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
61 #include <StepShape_ShapeDefinitionRepresentation.hxx>
62 #include <StepShape_ShapeRepresentation.hxx>
63 #include <StepShape_ShellBasedSurfaceModel.hxx>
64 #include <StepShape_VertexPoint.hxx>
65 #include <StepVisual_TessellatedItem.hxx>
66 #include <StepVisual_TessellatedShapeRepresentation.hxx>
67 #include <StepVisual_TessellatedSolid.hxx>
68 #include <TCollection_HAsciiString.hxx>
69 #include <TColStd_HSequenceOfTransient.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Compound.hxx>
74 #include <TopoDS_Iterator.hxx>
75 #include <TopoDS_Shape.hxx>
76 #include <TopoDS_Solid.hxx>
77 #include <TopoDSToStep_FacetedTool.hxx>
78 #include <TopoDSToStep_MakeBrepWithVoids.hxx>
79 #include <TopoDSToStep_MakeFacetedBrep.hxx>
80 #include <TopoDSToStep_MakeFacetedBrepAndBrepWithVoids.hxx>
81 #include <TopoDSToStep_MakeGeometricCurveSet.hxx>
82 #include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
83 #include <TopoDSToStep_MakeShellBasedSurfaceModel.hxx>
84 #include <TopoDSToStep_MakeStepVertex.hxx>
85 #include <TopoDSToStep_Tool.hxx>
86 #include <TopTools_HSequenceOfShape.hxx>
87 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
88 #include <TopTools_ListOfShape.hxx>
89 #include <Transfer_Binder.hxx>
90 #include <Transfer_Finder.hxx>
91 #include <Transfer_FinderProcess.hxx>
92 #include <Transfer_SequenceOfBinder.hxx>
93 #include <Transfer_SimpleBinderOfTransient.hxx>
94 #include <TransferBRep.hxx>
95 #include <TransferBRep_ShapeMapper.hxx>
96 #include <UnitsMethods.hxx>
98 #include <XSAlgo_AlgoContainer.hxx>
100 IMPLEMENT_STANDARD_RTTIEXT(STEPControl_ActorWrite,Transfer_ActorOfFinderProcess)
105 // Non-manifold topology processing (ssv; 10.11.2010)
106 // ============================================================================
107 // Function: DumpWhatIs
108 // Purpose: Use it in debug mode to dump your shapes
109 // ============================================================================
111 static void DumpWhatIs(const TopoDS_Shape& S) {
113 TopTools_MapOfShape aMapOfShape;
115 TopTools_ListOfShape aListOfShape;
116 aListOfShape.Append(S);
117 TopTools_ListIteratorOfListOfShape itL(aListOfShape);
118 Standard_Integer nbSolids = 0,
126 for( ; itL.More(); itL.Next() ) {
127 TopoDS_Iterator it( itL.Value() );
128 for ( ; it.More(); it.Next() ) {
129 TopoDS_Shape aSubShape = it.Value();
130 if ( !aMapOfShape.Add(aSubShape) )
132 aListOfShape.Append(aSubShape);
133 if (aSubShape.ShapeType() == TopAbs_SOLID)
135 if (aSubShape.ShapeType() == TopAbs_SHELL) {
136 if ( !aSubShape.Closed() )
140 if (aSubShape.ShapeType() == TopAbs_FACE)
142 if (aSubShape.ShapeType() == TopAbs_WIRE)
144 if (aSubShape.ShapeType() == TopAbs_EDGE)
146 if (aSubShape.ShapeType() == TopAbs_VERTEX)
151 std::cout << "//What is?// NB SOLIDS: " << nbSolids << std::endl;
152 std::cout << "//What is?// NB SHELLS: " << nbShells << std::endl;
153 std::cout << "//What is?// OPEN SHELLS: " << nbOpenShells << std::endl;
154 std::cout << "//What is?// CLOSED SHELLS: " << nbShells - nbOpenShells << std::endl;
155 std::cout << "//What is?// NB FACES: " << nbFaces << std::endl;
156 std::cout << "//What is?// NB WIRES: " << nbWires << std::endl;
157 std::cout << "//What is?// NB EDGES: " << nbEdges << std::endl;
158 std::cout << "//What is?// NB VERTEXES: " << nbVertexes << std::endl;
162 static Standard_Boolean hasGeometry(const TopoDS_Shape& theShape)
164 TopAbs_ShapeEnum aType = theShape.ShapeType();
166 if (aType == TopAbs_VERTEX)
168 return Standard_True;
170 else if (aType == TopAbs_EDGE)
172 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(theShape.TShape());
173 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
177 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
178 Standard_Boolean aHasGeometry = (CR->IsCurve3D() && !CR->Curve3D().IsNull())
179 || CR->IsCurveOnSurface()
180 || CR->IsRegularity()
181 || (CR->IsPolygon3D() && !CR->Polygon3D().IsNull())
182 || CR->IsPolygonOnTriangulation()
183 || CR->IsPolygonOnSurface();
185 return Standard_False;
188 return Standard_True;
190 else if (aType == TopAbs_FACE)
192 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(theShape.TShape());
193 if (!TF->Surface().IsNull())
195 return Standard_True;
200 TopoDS_Iterator anIt(theShape, Standard_False, Standard_False);
201 for (; anIt.More(); anIt.Next())
203 const TopoDS_Shape& aShape = anIt.Value();
204 Standard_Boolean aHasGeometry = hasGeometry(aShape);
206 return Standard_False;
208 return Standard_True;
211 return Standard_False;
214 //=======================================================================
215 // Function : IsManifoldShape
216 // Purpose : Used to define whether the passed shape has manifold
218 //=======================================================================
220 static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
222 Standard_Boolean aResult = Standard_True;
224 // Do not check nested Compounds
225 TopoDS_Compound aDirectShapes;
226 BRep_Builder aBrepBuilder;
227 aBrepBuilder.MakeCompound(aDirectShapes);
229 TopoDS_Iterator anIt(theShape);
230 for ( ; anIt.More(); anIt.Next() ) {
231 TopoDS_Shape aDirectChild = anIt.Value();
232 if (aDirectChild.ShapeType() != TopAbs_COMPOUND)
233 aBrepBuilder.Add(aDirectShapes, aDirectChild);
237 DumpWhatIs(aDirectShapes);
240 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
241 TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
243 Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
245 std::cout << "Checking whether the topology passed is manifold..." << std::endl;
249 for (Standard_Integer i = 1; i <= aNbEdges; i++) {
250 TopoDS_Edge aCurrentEdge = TopoDS::Edge( aMapEdgeFaces.FindKey(i) );
251 if ( !BRep_Tool::Degenerated(aCurrentEdge) ) {
252 Standard_Integer aNbAncestors = aMapEdgeFaces.FindFromIndex(i).Extent();
253 if (aNbAncestors > 2) {
254 aResult = Standard_False;
261 std::cout << "Check result: "
262 << (aResult ? "TRUE" : "FALSE") << std::endl;
268 //=======================================================================
269 //function : STEPControl_ActorWrite
271 //=======================================================================
273 STEPControl_ActorWrite::STEPControl_ActorWrite ()
274 : mygroup (0) , mytoler (-1.)
276 SetMode(STEPControl_ShellBasedSurfaceModel);
279 //=======================================================================
280 //method: getNMSSRForGroup
281 //purpose: allows to get NMSSR (NON_MANIFOLD_SURFACE_SHAPE_REPRESENTATION)
282 // STEP's entity for the group of shells (!) passed
283 //=======================================================================
285 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::getNMSSRForGroup(const Handle(TopTools_HSequenceOfShape)& shapeGroup,
286 const Handle(Transfer_FinderProcess)& FP,
287 Standard_Boolean& isNMSSRCreated) const
289 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) aResult;
291 if ( !shapeGroup.IsNull() ) {
292 for (Standard_Integer i = 1; i <= shapeGroup->Length(); i++) {
293 TopoDS_Shape aCurrentShape = shapeGroup->Value(i);
294 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper(FP, aCurrentShape);
295 if ( FP->FindTypedTransient(mapper, STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation), aResult) )
300 if ( aResult.IsNull() ) {
302 std::cout << "\nNew NMSSR created" << std::endl;
304 aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
305 isNMSSRCreated = Standard_True;
308 std::cout << "\nExisting NMSSR is used" << std::endl;
310 isNMSSRCreated = Standard_False;
316 //=======================================================================
317 //function : mergeInfoForNM
318 //purpose : bind already written shared faces to STEP entity for non-manifold
319 //=======================================================================
320 void STEPControl_ActorWrite::mergeInfoForNM(const Handle(Transfer_FinderProcess)& theFP,
321 const Handle(Standard_Transient) &theInfo) const
323 Handle(ShapeProcess_ShapeContext) aContext = Handle(ShapeProcess_ShapeContext)::DownCast ( theInfo );
324 if ( aContext.IsNull() ) return;
326 const TopTools_DataMapOfShapeShape &aMap = aContext->Map();
327 TopTools_DataMapIteratorOfDataMapOfShapeShape aShapeShapeIt(aMap);
329 for ( ; aShapeShapeIt.More(); aShapeShapeIt.Next() ) {
330 TopoDS_Shape anOrig = aShapeShapeIt.Key(), aRes = aShapeShapeIt.Value();
331 if (anOrig.ShapeType() != TopAbs_FACE)
334 Handle(TransferBRep_ShapeMapper) anOrigMapper= TransferBRep::ShapeMapper ( theFP, anOrig);
335 Handle(Transfer_Binder) anOrigBinder = theFP->Find ( anOrigMapper );
336 if (anOrigBinder.IsNull())
339 Handle(TransferBRep_ShapeMapper) aResMapper = TransferBRep::ShapeMapper ( theFP, aRes );
340 theFP->Bind(aResMapper, anOrigBinder);
345 //=======================================================================
348 //=======================================================================
350 void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
353 case STEPControl_AsIs : ModeTrans() = 0; break;
354 case STEPControl_ManifoldSolidBrep : ModeTrans() = 3; break;
355 case STEPControl_BrepWithVoids : ModeTrans() = 5; break;
356 case STEPControl_FacetedBrep : ModeTrans() = 1; break;
357 case STEPControl_FacetedBrepAndBrepWithVoids : ModeTrans() = 6; break;
358 case STEPControl_ShellBasedSurfaceModel : ModeTrans() = 2; break;
359 case STEPControl_GeometricCurveSet : ModeTrans() = 4; break;
360 case STEPControl_Hybrid : ModeTrans() = 0; break; // PAS IMPLEMENTE !!
365 //=======================================================================
368 //=======================================================================
370 STEPControl_StepModelType STEPControl_ActorWrite::Mode () const
372 switch (themodetrans) {
373 case 0 : return STEPControl_AsIs;
374 case 1 : return STEPControl_FacetedBrep;
375 case 2 : return STEPControl_ShellBasedSurfaceModel;
376 case 3 : return STEPControl_ManifoldSolidBrep;
377 case 4 : return STEPControl_GeometricCurveSet;
378 case 5 : return STEPControl_BrepWithVoids;
379 case 6 : return STEPControl_FacetedBrepAndBrepWithVoids;
382 return STEPControl_AsIs;
385 //=======================================================================
386 //function : SetGroupMode
388 //=======================================================================
390 void STEPControl_ActorWrite::SetGroupMode (const Standard_Integer mode)
392 if (mode >= 0) mygroup = mode;
395 //=======================================================================
396 //function : GroupMode
398 //=======================================================================
400 Standard_Integer STEPControl_ActorWrite::GroupMode () const
405 //=======================================================================
406 //function : SetTolerance
408 //=======================================================================
410 void STEPControl_ActorWrite::SetTolerance (const Standard_Real Tol)
415 //=======================================================================
416 //function : Recognize
417 // ATTENTION, Recognize doit s aligner sur ce que Transfer sait faire
419 //=======================================================================
421 Standard_Boolean STEPControl_ActorWrite::Recognize (const Handle(Transfer_Finder)& start)
423 STEPControl_StepModelType mymode = Mode();
424 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
425 if (mapper.IsNull()) return Standard_False;
426 if (mymode == STEPControl_AsIs) return Standard_True;
428 Standard_Boolean yasolid = Standard_False, yashell = Standard_False,
429 yaface = Standard_False;
431 TopoDS_Shape theShape, aShape;
432 // theShape = TopoDSToStep::DirectFaces(mapper->Value());
433 theShape = mapper->Value(); // pour une reconnaissance c est bien assez
435 if (theShape.ShapeType() == TopAbs_COMPOUND) {
437 TopExp_Explorer SolidExp, ShellExp, FaceExp;
439 for (SolidExp.Init(theShape, TopAbs_SOLID);
440 SolidExp.More();SolidExp.Next()) yasolid = Standard_True;
441 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
442 ShellExp.More();ShellExp.Next()) yashell = Standard_True;
443 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
444 FaceExp.More();FaceExp.Next()) yaface = Standard_True;
446 else if (theShape.ShapeType() == TopAbs_SOLID) yasolid = Standard_True;
447 else if (theShape.ShapeType() == TopAbs_SHELL) yashell = Standard_True;
448 else if (theShape.ShapeType() == TopAbs_FACE) yaface = Standard_True;
449 else if (mymode != STEPControl_GeometricCurveSet) return Standard_False;
452 // Faceted : il est OBLIGATOIRE d avoir des surfaces support Plane et des
453 // courbes 3D Line (pcurves ignorees)
455 if (mymode == STEPControl_FacetedBrep || mymode == STEPControl_FacetedBrepAndBrepWithVoids) {
456 for (TopExp_Explorer ffac(theShape,TopAbs_FACE); ffac.More(); ffac.Next()) {
457 const TopoDS_Face& F = TopoDS::Face (ffac.Current());
458 TopLoc_Location locbid;
459 Handle(Geom_Surface) surf = BRep_Tool::Surface (F,locbid);
460 if (surf.IsNull() || !surf->IsKind(STANDARD_TYPE(Geom_Plane)) ) return Standard_False;
462 for (TopExp_Explorer fedg(theShape,TopAbs_EDGE); fedg.More(); fedg.Next()) {
463 const TopoDS_Edge& E = TopoDS::Edge (fedg.Current());
464 TopLoc_Location locbid; Standard_Real first,last;
465 Handle(Geom_Curve) curv = BRep_Tool::Curve (E,locbid,first,last);
466 if (curv.IsNull() || !curv->IsKind(STANDARD_TYPE(Geom_Line)) ) return Standard_False;
471 case STEPControl_ManifoldSolidBrep: return (yasolid || yashell);
472 case STEPControl_BrepWithVoids:
473 case STEPControl_FacetedBrep:
474 case STEPControl_FacetedBrepAndBrepWithVoids: return yasolid;
475 case STEPControl_ShellBasedSurfaceModel:
476 return (yasolid || yashell || yaface);
477 case STEPControl_GeometricCurveSet: return Standard_True; // tout OK
480 return Standard_False;
484 // ######## MAKE PRODUCT DATA + CONTEXT ########
486 //=======================================================================
487 //function : Transfer
489 //=======================================================================
491 Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_Finder)& start,
492 const Handle(Transfer_FinderProcess)& FP,
493 const Message_ProgressRange& theProgress)
495 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
497 if (mapper.IsNull()) return NullResult();
498 TopoDS_Shape shape = mapper->Value();
501 Handle(StepData_StepModel) model = Handle(StepData_StepModel)::DownCast ( FP->Model() );
502 if ( ! model.IsNull() ) myContext.SetModel ( model ); //: abv 04.11.00: take APD from model
503 myContext.AddAPD ( Standard_False ); // update APD
504 myContext.SetLevel ( 1 ); // set assembly level to 1 (to ensure)
505 if (!model->IsInitializedUnit())
507 XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
508 model->SetLocalLengthUnit(UnitsMethods::GetCasCadeLengthUnit());
510 Standard_Real aLFactor = model->WriteLengthUnit();
511 aLFactor /= model->LocalLengthUnit();
512 Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
513 StepData_GlobalFactors::Intance().InitializeFactors (aLFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
516 STEPConstruct_Part SDRTool;
517 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
518 Handle(StepShape_ShapeDefinitionRepresentation) sdr = SDRTool.SDRValue();
521 Handle(Transfer_Binder) resbind = TransferShape (mapper,sdr,FP, 0L, Standard_True, theProgress);
523 // Handle(StepShape_ShapeRepresentation) resultat;
524 // FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
525 // sdr->SetUsedRepresentation (resultat);
527 // create binder with all root entities produced from shape
528 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForPart ( SDRTool );
529 Handle(Transfer_Binder) resprod = TransientResult ( myContext.GetAPD() );
530 for ( Standard_Integer i=1; i <= roots->Length(); i++ )
531 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
532 resprod->AddResult(resbind);
535 //FP->Bind (mapper,resprod);
536 myContext.NextIndex();
540 //==========================================
542 static Standard_Real UsedTolerance (const Standard_Real mytoler,
543 const TopoDS_Shape& theShape)
546 // COMPUTING 3D TOLERANCE
547 // Either from Session, or Computed (Least,Average, or Greatest)
548 // Then given to TopoDSToStep_Tool
550 Standard_Real Tol = mytoler;
551 Standard_Integer tolmod = Interface_Static::IVal("write.precision.mode");
552 if (Tol <= 0 && tolmod == 2) Tol =
553 Interface_Static::RVal("write.precision.val");
555 ShapeAnalysis_ShapeTolerance stu;
556 Tol = stu.Tolerance (theShape,tolmod);
557 // Par defaut, on prend une tolerance moyenne, on elimine les aberrations
558 Tol = Interface_MSG::Intervalled (Tol * 1.5); // arrondi a 1 2 5 ...
560 if (Tol == 0) Tol = 1.e-07; // minimum ...
565 //=======================================================================
566 //function : IsAssembly
568 //=======================================================================
569 // if GroupMode is >1 downgrades all compounds having single subshape to that
572 Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
574 if ( ! GroupMode() || S.ShapeType() != TopAbs_COMPOUND ) return Standard_False;
575 // PTV 16.09.2002 OCC725 for storing compound of vertices
576 if (Interface_Static::IVal("write.step.vertex.mode") == 0) {//bug 23950
577 if (S.ShapeType() == TopAbs_COMPOUND ) {
578 Standard_Boolean IsOnlyVertices = Standard_True;
579 TopoDS_Iterator anItr( S );
580 for ( ; anItr.More(); anItr.Next() ) {
581 if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
582 IsOnlyVertices = Standard_False;
586 if ( IsOnlyVertices )
587 return Standard_False;
590 if ( GroupMode() ==1 ) return Standard_True;
591 TopoDS_Iterator it ( S );
592 if ( ! it.More() ) return Standard_False;
593 TopoDS_Shape shape = it.Value();
595 if ( it.More() ) return Standard_True;
597 return IsAssembly ( S );
600 //=======================================================================
601 //function : TransferShape
603 //=======================================================================
606 static void UpdateMap (const TopoDS_Shape &shape,
607 BRepTools_Modifier &M1,
608 BRepTools_Modifier &M2,
609 const Handle(Transfer_FinderProcess) &FinderProcess)
611 TopoDS_Shape S = M1.ModifiedShape ( shape );
612 S = M2.ModifiedShape ( S );
613 if ( S == shape ) return;
615 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess, S );
616 Handle(Transfer_Binder) binder = FinderProcess->Find ( mapper );
617 if ( ! binder.IsNull() ) {
618 mapper = TransferBRep::ShapeMapper ( FinderProcess, shape );
619 FinderProcess->Bind ( mapper, binder );
622 for ( TopoDS_Iterator it(shape); it.More(); it.Next() )
623 UpdateMap ( it.Value(), M1, M2, FinderProcess );
627 // PTV 16.09.2002 added for transferring vertices.
628 static Standard_Boolean transferVertex (const Handle(Transfer_FinderProcess)& FP,
629 Handle(StepShape_HArray1OfGeometricSetSelect)& aGSS,
630 const TopoDS_Shape& aShVrtx,
631 const Standard_Integer theNum)
633 Standard_Boolean IsDone = Standard_False;
634 MoniTool_DataMapOfShapeTransient aMap;
635 TopoDSToStep_Tool aTool(aMap, Standard_True);
636 TopoDSToStep_MakeStepVertex aMkVrtx ( TopoDS::Vertex(aShVrtx), aTool, FP );
638 if (!aMkVrtx.IsDone())
641 Handle(StepShape_VertexPoint) aVP =
642 Handle(StepShape_VertexPoint)::DownCast(aTool.Find(aShVrtx));
646 StepShape_GeometricSetSelect select;
647 select.SetValue(aVP->VertexGeometry());
648 // add current result
649 aGSS->SetValue( theNum, select );
650 IsDone = Standard_True;
655 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape
656 (const Handle(Transfer_Finder)& start,
657 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
658 const Handle(Transfer_FinderProcess)& FP,
659 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
660 const Standard_Boolean isManifold,
661 const Message_ProgressRange& theProgress)
663 STEPControl_StepModelType mymode = Mode();
664 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
665 Handle(Transfer_Binder) binder;
667 // Indicates whether to use an existing NMSSR to write items to (ss; 13.11.2010)
668 Standard_Boolean useExistingNMSSR = Standard_False;
670 if (mapper.IsNull()) return binder;
671 TopoDS_Shape theShape = mapper->Value();
673 if (theShape.IsNull()) return binder;
675 // INDIVIDUAL SHAPE ALREADY TRANSFERRED : RETURN IT !
676 binder = FP->Find(start);
677 if (!binder.IsNull()) { if (!binder->HasResult()) binder.Nullify(); }
678 if (!binder.IsNull()) {
679 //:abv 20.05.02: writing box & face from it (shared) in one compound
680 // as assembly - while face already translated, it should be
681 // re-translated to break sharing
683 std::cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << std::endl;
688 // MODE ASSEMBLY : if Compound, (sub-)assembly
689 if ( IsAssembly(theShape) )
690 return TransferCompound(start, SDR0, FP, theProgress);
692 Message_ProgressScope aPSRoot(theProgress, NULL, 2);
694 // [BEGIN] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
695 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
696 Handle(Transfer_Binder) aNMBinder;
697 if (isNMMode && !GroupMode() && theShape.ShapeType() == TopAbs_COMPOUND) {
698 TopoDS_Compound aNMCompound;
699 TopoDS_Compound aManifoldCompound;
700 BRep_Builder brepBuilder;
702 // Create empty Compounds
703 brepBuilder.MakeCompound(aManifoldCompound);
704 brepBuilder.MakeCompound(aNMCompound);
706 // Indicates whether there is only non-manifold topology detected
707 // (there is no manifold topology found in the Compound passed)
708 Standard_Boolean isOnlyNonManifold = Standard_False;
710 // Find a Compound containing non-manifold topology.
711 // NOTE: only one such Compound must exist in the entire Compound passed
712 if ( !IsManifoldShape(theShape) ) {
713 aNMCompound = TopoDS::Compound(theShape);
714 isOnlyNonManifold = Standard_True;
717 TopTools_ListOfShape aListOfShapes;
718 TopTools_ListOfShape aListOfManifoldShapes;
719 aListOfShapes.Append(theShape);
721 TopTools_ListIteratorOfListOfShape itL(aListOfShapes);
722 for ( ; itL.More(); itL.Next() ) {
723 TopoDS_Shape aParentShape = itL.Value();
724 TopoDS_Iterator it(aParentShape);
725 for ( ; it.More(); it.Next() ) {
726 TopoDS_Shape aSubShape = it.Value();
727 if (aSubShape.ShapeType() == TopAbs_COMPOUND && !IsManifoldShape(aSubShape) )
728 aNMCompound = TopoDS::Compound(aSubShape);
729 else if (aSubShape.ShapeType() == TopAbs_COMPOUND)
730 aListOfShapes.Append(aSubShape);
732 aListOfManifoldShapes.Append(aSubShape);
736 // Group manifold topology together.
737 // NOTE: there is no sense that initial Compound structure was lost as
738 // group mode is set to 0 (no Assemblies are mapped)
739 for ( itL.Initialize(aListOfManifoldShapes); itL.More(); itL.Next() ) {
740 TopoDS_Shape aCurrentManiShape = itL.Value();
741 brepBuilder.Add(aManifoldCompound, aCurrentManiShape);
746 // Process only manifold topology in the current TransferShape invocation.
747 // Invoke TransferShape for non-manifold topology separately (see below)
748 theShape = aManifoldCompound;
750 // List of items to transfer
751 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
752 // Non-manifold group to pass into TransferShape with each shape from RepItemSeq
753 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
755 // Transfer Solids to closed Shells. Prepare RepItemSeq & NonManifoldGroup
756 for ( TopoDS_Iterator iter(aNMCompound); iter.More(); iter.Next() ) {
757 TopoDS_Shape aSubShape = iter.Value();
758 if (aSubShape.ShapeType() == TopAbs_SOLID) {
759 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
760 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
761 aSubShell.Closed(Standard_True);
762 RepItemSeq->Append(aSubShell);
763 NonManifoldGroup->Append(aSubShell);
766 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
767 RepItemSeq->Append(aSubShape);
768 NonManifoldGroup->Append(aSubShape);
771 RepItemSeq->Append( iter.Value() );
774 Standard_Integer aNMItemsNb = RepItemSeq->Length();
776 // In case of pure manifold topology do nothing; theShape is processed as usual (see below)
777 if (aNMItemsNb > 0) {
779 // Prepare SDR for non-manifold group. This SDR will be linked to NMSSR by means
780 // of TransferShape invocation. SDR is not created if there is no any manifold
781 // topology in the passed Compound. If topology is pure non-manifold, SDR0 (passed)
783 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
784 if (isOnlyNonManifold)
787 STEPConstruct_Part SDRTool;
788 SDRTool.MakeSDR( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
789 sdr = SDRTool.SDRValue();
792 aNMBinder = TransientResult(sdr);
794 // Complete SDR with shape representations.
795 // NOTE: aNMBinder is connected now with this SDR. It will be added to the resulting
796 // binder in the end of this invocation of TransferShape
797 Message_ProgressScope aPS (aPSRoot.Next(), NULL, aNMItemsNb);
798 for (Standard_Integer i = 1; i <= aNMItemsNb && aPS.More(); i++) {
799 Handle(TransferBRep_ShapeMapper) aMapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
800 TransferShape(aMapper, sdr, FP, NonManifoldGroup, Standard_False, aPS.Next());
803 // Nothing else needed for pure non-manifold topology, return
804 if (isOnlyNonManifold)
810 // [END] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
812 if (aPSRoot.UserBreak())
813 return Handle(Transfer_Binder)();
815 // create a list of items to translate
816 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
818 Standard_Boolean isSeparateVertices =
819 Interface_Static::IVal("write.step.vertex.mode") == 0;//bug 23950
820 // PTV 16.09.2002 OCC725 separate shape from solo vertices.
821 Standard_Boolean isOnlyVertices = Standard_False;
822 if (theShape.ShapeType() == TopAbs_COMPOUND) {
823 Standard_Integer countVrtx = 0;
824 Standard_Integer countSh = 0;
825 TopoDS_Compound aNewShape, aCompOfVrtx;
827 aB.MakeCompound(aNewShape);
828 aB.MakeCompound(aCompOfVrtx);
829 TopoDS_Iterator anCompIt(theShape);
830 if (isSeparateVertices) {
831 for (; anCompIt.More(); anCompIt.Next()) {
832 TopoDS_Shape aCurSh = anCompIt.Value();
833 if (aCurSh.ShapeType() != TopAbs_VERTEX) {
834 aB.Add(aNewShape, aCurSh);
838 aB.Add(aCompOfVrtx, aCurSh);
842 // replace the shapes
844 theShape = aNewShape;
846 RepItemSeq->Append(aCompOfVrtx);
848 isOnlyVertices = Standard_True;
852 if (theShape.ShapeType() == TopAbs_COMPOUND) {
853 TopExp_Explorer SolidExp, ShellExp, FaceExp;
854 if (mymode != STEPControl_GeometricCurveSet) {
855 for (SolidExp.Init(theShape, TopAbs_SOLID);
856 SolidExp.More();SolidExp.Next()) {
857 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
859 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
860 ShellExp.More();ShellExp.Next()) {
861 RepItemSeq->Append(TopoDS::Shell(ShellExp.Current()));
864 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
865 FaceExp.More();FaceExp.Next()) {
866 RepItemSeq->Append(TopoDS::Face(FaceExp.Current()));
871 RepItemSeq->Append(theShape); //:j1
873 if(mymode == STEPControl_AsIs) {
874 TopExp_Explorer WireExp, EdgeExp;
875 for (WireExp.Init(theShape, TopAbs_WIRE, TopAbs_FACE);
876 WireExp.More();WireExp.Next())
877 RepItemSeq->Append(TopoDS::Wire(WireExp.Current()));
878 for (EdgeExp.Init(theShape, TopAbs_EDGE, TopAbs_WIRE);
879 EdgeExp.More();EdgeExp.Next())
880 RepItemSeq->Append(TopoDS::Edge(EdgeExp.Current()));
884 else if (theShape.ShapeType() == TopAbs_SOLID) {
885 RepItemSeq->Append(TopoDS::Solid(theShape));
887 else if (theShape.ShapeType() == TopAbs_SHELL) {
888 RepItemSeq->Append(TopoDS::Shell(theShape));
890 else if (theShape.ShapeType() == TopAbs_FACE) {
891 RepItemSeq->Append(TopoDS::Face(theShape));
893 else if (theShape.ShapeType() == TopAbs_COMPSOLID) {
894 FP->AddWarning(start,"NonManifold COMPSOLID was translated like a set of SOLIDs");
895 if ( GroupMode() > 0)
896 return TransferCompound(start, SDR0, FP, aPSRoot.Next());
898 TopExp_Explorer SolidExp;
899 for (SolidExp.Init(theShape, TopAbs_SOLID);
900 SolidExp.More();SolidExp.Next()) {
901 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
906 else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
907 FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
910 else RepItemSeq->Append (theShape);
912 // COMPUTING 3D TOLERANCE
913 // Either from Session, or Computed (Least,Average, or Greatest)
914 // Then given to TopoDSToStep_Tool
915 Standard_Real Tol = UsedTolerance (mytoler,theShape);
917 // Create a STEP-Entity for each TopoDS_Shape
918 // according to the current StepModelMode
920 Standard_Integer nbs = RepItemSeq->Length();
921 Handle(TColStd_HSequenceOfTransient) ItemSeq =
922 new TColStd_HSequenceOfTransient();
924 //ptv 10.11.00: allow to write empty Compound: if (GroupMode() >0)
925 ItemSeq->Append (myContext.GetDefaultAxis());
926 STEPControl_StepModelType trmode = mymode;
927 Message_ProgressScope aPS (aPSRoot.Next(), NULL, nbs);
928 for (Standard_Integer i = 1; i <= nbs && aPS.More(); i++) {
929 TopoDS_Shape xShape = RepItemSeq->Value(i);
931 if(mymode == STEPControl_AsIs) {
932 switch(xShape.ShapeType()) {
933 case TopAbs_SOLID : trmode = STEPControl_ManifoldSolidBrep;break;
934 case TopAbs_SHELL : trmode = STEPControl_ShellBasedSurfaceModel; break;
935 case TopAbs_FACE : trmode = STEPControl_ShellBasedSurfaceModel;break;
936 default : trmode =STEPControl_GeometricCurveSet; break;
939 //:abv 24Jan99 CAX-IF TRJ3: expanded Shape Processing
940 // TopoDS_Shape aShape = xShape;
941 // eliminate conical surfaces with negative semiangles
942 // Handle(TopoDSToStep_ConicalSurfModif) CSM = new TopoDSToStep_ConicalSurfModif();
943 // BRepTools_Modifier CSMT(aShape,CSM);
944 // if ( CSMT.IsDone() ) aShape = CSMT.ModifiedShape ( aShape );
945 // // eliminate indirect elementary surfaces
946 // Handle(TopoDSToStep_DirectModification) DM = new TopoDSToStep_DirectModification();
947 // BRepTools_Modifier DMT(aShape,DM);
948 // if ( DMT.IsDone() ) aShape = DMT.ModifiedShape ( aShape );
949 //// aShape = TopoDSToStep::DirectFaces(xShape);
950 Message_ProgressScope aPS1(aPS.Next(), NULL, 2);
952 TopoDS_Shape aShape = xShape;
953 Handle(Standard_Transient) info;
955 if (hasGeometry(aShape))
957 Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
959 aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol,
960 "write.step.resource.name",
961 "write.step.sequence", info,
963 if (aPS1.UserBreak())
964 return Handle(Transfer_Binder)();
969 mergeInfoForNM(FP, info);
972 // create a STEP entity corresponding to shape
973 Handle(StepGeom_GeometricRepresentationItem) item, itemTess;
976 case STEPControl_ManifoldSolidBrep:
978 if (aShape.ShapeType() == TopAbs_SOLID) {
979 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
981 //:d6 abv 13 Mar 98: if solid has more than 1 shell,
982 // try to treat it as solid with voids
983 Standard_Integer nbShells = 0;
984 for ( TopoDS_Iterator It ( aSolid ); It.More(); It.Next() )
985 if (It.Value().ShapeType() == TopAbs_SHELL) nbShells++;
987 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP, aPS1.Next());
988 MkBRepWithVoids.Tolerance() = Tol;
989 if (MkBRepWithVoids.IsDone())
991 item = MkBRepWithVoids.Value();
992 itemTess = MkBRepWithVoids.TessellatedValue();
994 else nbShells = 1; //smth went wrong; let it will be just Manifold
996 if ( nbShells ==1 ) {
997 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aSolid,FP, aPS1.Next());
998 MkManifoldSolidBrep.Tolerance() = Tol;
999 if (MkManifoldSolidBrep.IsDone())
1001 item = MkManifoldSolidBrep.Value();
1002 itemTess = MkManifoldSolidBrep.TessellatedValue();
1006 else if (aShape.ShapeType() == TopAbs_SHELL) {
1007 TopoDS_Shell aShell = TopoDS::Shell(aShape);
1008 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aShell,FP, aPS1.Next());
1009 MkManifoldSolidBrep.Tolerance() = Tol;
1010 if (MkManifoldSolidBrep.IsDone())
1012 item = MkManifoldSolidBrep.Value();
1013 itemTess = MkManifoldSolidBrep.TessellatedValue();
1018 case STEPControl_BrepWithVoids:
1020 if (aShape.ShapeType() == TopAbs_SOLID) {
1021 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1022 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP, aPS1.Next());
1023 MkBRepWithVoids.Tolerance() = Tol;
1024 if (MkBRepWithVoids.IsDone())
1026 item = MkBRepWithVoids.Value();
1027 itemTess = MkBRepWithVoids.TessellatedValue();
1032 case STEPControl_FacetedBrep:
1034 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
1035 if (facErr != TopoDSToStep_FacetedDone) {
1036 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
1037 if (facErr == TopoDSToStep_SurfaceNotPlane) {
1038 FP->AddFail(start,"-- The TopoDS_Face is not plane");
1040 else if (facErr == TopoDSToStep_PCurveNotLinear) {
1041 FP->AddFail(start,"-- The Face contains non linear PCurves");
1045 if (aShape.ShapeType() == TopAbs_SOLID) {
1046 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1047 TopoDSToStep_MakeFacetedBrep MkFacetedBrep(aSolid,FP, aPS1.Next());
1048 MkFacetedBrep.Tolerance() = Tol;
1049 if (MkFacetedBrep.IsDone())
1051 item = MkFacetedBrep.Value();
1052 itemTess = MkFacetedBrep.TessellatedValue();
1057 case STEPControl_FacetedBrepAndBrepWithVoids:
1059 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
1060 if (facErr != TopoDSToStep_FacetedDone) {
1061 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
1062 if (facErr == TopoDSToStep_SurfaceNotPlane) {
1063 FP->AddFail(start,"-- The TopoDS_Face is not plane");
1065 else if (facErr == TopoDSToStep_PCurveNotLinear) {
1066 FP->AddFail(start,"-- The Face contains non linear PCurves");
1070 if (aShape.ShapeType() == TopAbs_SOLID) {
1071 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1072 TopoDSToStep_MakeFacetedBrepAndBrepWithVoids
1073 MkFacetedBrepAndBrepWithVoids(aSolid,FP, aPS1.Next());
1074 MkFacetedBrepAndBrepWithVoids.Tolerance() = Tol;
1075 if (MkFacetedBrepAndBrepWithVoids.IsDone())
1077 item = MkFacetedBrepAndBrepWithVoids.Value();
1078 itemTess = MkFacetedBrepAndBrepWithVoids.TessellatedValue();
1083 case STEPControl_ShellBasedSurfaceModel:
1085 if (aShape.ShapeType() == TopAbs_SOLID) {
1086 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1087 TopoDSToStep_MakeShellBasedSurfaceModel
1088 MkShellBasedSurfaceModel(aSolid, FP, aPS1.Next());
1089 MkShellBasedSurfaceModel.Tolerance() = Tol;
1090 if (MkShellBasedSurfaceModel.IsDone())
1092 item = MkShellBasedSurfaceModel.Value();
1093 itemTess = MkShellBasedSurfaceModel.TessellatedValue();
1096 else if (aShape.ShapeType() == TopAbs_SHELL) {
1097 TopoDS_Shell aShell = TopoDS::Shell(aShape);
1098 // Non-manifold topology is stored via NMSSR containing series of SBSM (ssv; 13.11.2010)
1099 TopoDSToStep_MakeShellBasedSurfaceModel MkShellBasedSurfaceModel(aShell, FP, aPS1.Next());
1100 MkShellBasedSurfaceModel.Tolerance() = Tol;
1101 if (MkShellBasedSurfaceModel.IsDone())
1103 item = MkShellBasedSurfaceModel.Value();
1104 itemTess = MkShellBasedSurfaceModel.TessellatedValue();
1107 else if (aShape.ShapeType() == TopAbs_FACE) {
1108 TopoDS_Face aFace = TopoDS::Face(aShape);
1109 TopoDSToStep_MakeShellBasedSurfaceModel
1110 MkShellBasedSurfaceModel(aFace, FP, aPS1.Next());
1111 MkShellBasedSurfaceModel.Tolerance() = Tol;
1112 if (MkShellBasedSurfaceModel.IsDone())
1114 item = MkShellBasedSurfaceModel.Value();
1115 itemTess = MkShellBasedSurfaceModel.TessellatedValue();
1120 case STEPControl_GeometricCurveSet:
1122 TopoDSToStep_MakeGeometricCurveSet MkGeometricCurveSet(aShape,FP);
1123 MkGeometricCurveSet.Tolerance() = Tol;
1124 if (MkGeometricCurveSet.IsDone()) {
1125 item = MkGeometricCurveSet.Value();
1127 // PTV 22.08.2002 OCC609 ------------------------- begin --------------------
1128 // modified by PTV 16.09.2002 OCC725
1129 else if (aShape.ShapeType() == TopAbs_COMPOUND ||
1130 aShape.ShapeType() == TopAbs_VERTEX) {
1131 // it is compound with solo vertices.
1132 Standard_Integer aNbVrtx = 0;
1133 Standard_Integer curNb = 0;
1134 TopExp_Explorer anExp (aShape, TopAbs_VERTEX);
1135 for ( ; anExp.More(); anExp.Next() ) {
1136 if ( anExp.Current().ShapeType() != TopAbs_VERTEX )
1141 // create new geometric curve set for all vertices
1142 Handle(StepShape_HArray1OfGeometricSetSelect) aGSS =
1143 new StepShape_HArray1OfGeometricSetSelect(1,aNbVrtx);
1144 Handle(TCollection_HAsciiString) empty = new TCollection_HAsciiString("");
1145 Handle(StepShape_GeometricCurveSet) aGCSet =
1146 new StepShape_GeometricCurveSet;
1147 aGCSet->SetName(empty);
1148 // iterates on compound with vertices and traces each vertex
1149 for ( anExp.ReInit() ; anExp.More(); anExp.Next() ) {
1150 TopoDS_Shape aVertex = anExp.Current();
1151 if ( aVertex.ShapeType() != TopAbs_VERTEX )
1154 transferVertex (FP, aGSS, aVertex, curNb);
1155 } // end of iteration on compound with vertices.
1156 aGCSet->SetElements(aGSS);
1158 } // end of check that number of vertices is not null
1160 // PTV 22.08.2002 OCC609------------------------- end --------------------
1165 if ( item.IsNull() && itemTess.IsNull() ) continue;
1167 // add resulting item to the FP
1170 ItemSeq->Append(item);
1171 Handle(TransferBRep_ShapeMapper) submapper;
1172 if (xShape.IsSame(mapper->Value()))
1173 submapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1174 if (submapper.IsNull())
1175 submapper = TransferBRep::ShapeMapper(FP, xShape);
1176 Handle(Transfer_Binder) subbind = FP->Find(submapper);
1177 if (subbind.IsNull())
1179 subbind = TransientResult(item);
1180 FP->Bind(submapper, subbind);
1183 subbind->AddResult(TransientResult(item));
1185 if (!itemTess.IsNull())
1187 ItemSeq->Append(itemTess);
1188 Handle(TransferBRep_ShapeMapper) submapper;
1189 if (xShape.IsSame(mapper->Value()))
1190 submapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1191 if (submapper.IsNull())
1192 submapper = TransferBRep::ShapeMapper(FP, xShape);
1193 Handle(Transfer_Binder) subbind = FP->Find(submapper);
1194 if (subbind.IsNull())
1196 subbind = TransientResult(itemTess);
1197 FP->Bind(submapper, subbind);
1200 subbind->AddResult(TransientResult(itemTess));
1203 //:abv 24Jan99 CAX-IF TRJ3: Update FinderProcess map to take into account shape processing
1204 // UpdateMap ( xShape, CSMT, DMT, FP );
1206 XSAlgo::AlgoContainer()->MergeTransferInfo(FP, info);
1209 // - Make Shape Representation
1210 Standard_Integer nCc1 = ItemSeq->Length();
1212 FP->AddFail(start,"The Shape has not the appropriate type");
1215 Handle(StepShape_ShapeRepresentation) shapeRep;
1216 if ( theShape.ShapeType() == TopAbs_SHAPE ) { // for external references
1217 shapeRep = new StepShape_ShapeRepresentation;
1221 case STEPControl_ManifoldSolidBrep:
1222 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1224 case STEPControl_FacetedBrep:
1225 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1227 // NOTE: STEPControl_AsIs mode is normally used to transfer non-manifold topology.
1228 // However, as ShellBasedSurfaceModel is used in non-manifold processing
1229 // internally, STEPControl_ShellBasedSurfaceModel is also adjusted to
1230 // be able to work with non-manifold cases
1231 case STEPControl_ShellBasedSurfaceModel:
1233 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1235 Standard_Boolean isNewNMSSRCreated;
1236 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1237 useExistingNMSSR = !isNewNMSSRCreated;
1240 case STEPControl_GeometricCurveSet:
1241 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1243 case STEPControl_AsIs :
1246 if(trmode == STEPControl_ManifoldSolidBrep)
1247 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1248 else if(trmode == STEPControl_ShellBasedSurfaceModel)
1249 // Process non-manifold topology separately (ssv; 13.11.2010)
1251 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1253 Standard_Boolean isNewNMSSRCreated;
1254 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1255 useExistingNMSSR = !isNewNMSSRCreated;
1257 else if(trmode == STEPControl_GeometricCurveSet)
1258 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1259 else if(trmode ==STEPControl_FacetedBrep)
1260 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1262 else shapeRep = new StepShape_ShapeRepresentation;
1268 if(shapeRep.IsNull()) {
1269 Handle(Transfer_Binder) resb;
1273 Handle(StepRepr_HArray1OfRepresentationItem) items =
1274 new StepRepr_HArray1OfRepresentationItem(1,nCc1);
1276 for (Standard_Integer rep = 1; rep <= nCc1; rep++) {
1277 Handle(StepRepr_RepresentationItem) repit =
1278 GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep));
1279 items->SetValue(rep,repit);
1281 Standard_Integer ap = Interface_Static::IVal("write.step.schema");
1282 Transfer_SequenceOfBinder aSeqBindRelation;
1283 if(ap == 3 && nbs > 1) {
1284 Standard_Integer j = 1;
1285 if(items->Value(j)->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d))) {
1286 Handle(StepRepr_HArray1OfRepresentationItem) axis =
1287 new StepRepr_HArray1OfRepresentationItem(1,1);
1288 axis->SetValue(1,items->Value(j++));
1289 shapeRep->SetItems(axis);
1291 for (; j <= items->Length(); j++) {
1293 Handle(StepShape_ShapeRepresentation) ShapeRepr1;
1294 if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep)))
1295 ShapeRepr1 = new StepShape_AdvancedBrepShapeRepresentation;
1296 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel)))
1297 ShapeRepr1 = new StepShape_ManifoldSurfaceShapeRepresentation;
1298 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_GeometricCurveSet)))
1299 ShapeRepr1 = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1300 else if (items->Value(j)->IsKind(STANDARD_TYPE(StepShape_FacetedBrep)))
1301 ShapeRepr1 = new StepShape_FacetedBrepShapeRepresentation;
1302 else if (items->Value(j)->IsKind(STANDARD_TYPE(StepVisual_TessellatedItem)))
1303 ShapeRepr1 = new StepVisual_TessellatedShapeRepresentation;
1304 else ShapeRepr1 = new StepShape_ShapeRepresentation;
1306 Handle(StepRepr_HArray1OfRepresentationItem) repr1 = new StepRepr_HArray1OfRepresentationItem(1,2);
1307 repr1->SetValue(1,myContext.GetDefaultAxis());
1308 repr1->SetValue(2,items->Value(j));
1309 ShapeRepr1->SetItems(repr1);
1310 STEPConstruct_UnitContext mk1;
1312 ShapeRepr1->SetContextOfItems(mk1.Value()); // la tolerance, voir au debut
1313 ShapeRepr1->SetName (new TCollection_HAsciiString(""));
1315 Handle(StepRepr_ShapeRepresentationRelationship) aShapeRel = new StepRepr_ShapeRepresentationRelationship;
1316 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
1317 Handle(TCollection_HAsciiString) aDescr = new TCollection_HAsciiString("");
1318 aShapeRel->SetName(aName);
1319 aShapeRel->SetDescription(aDescr);
1320 aShapeRel->SetRep2(shapeRep);
1321 aShapeRel->SetRep1(ShapeRepr1);
1323 aSeqBindRelation.Append(TransientResult (aShapeRel));
1327 Standard_Integer nC = 0;
1328 for (Standard_Integer i = 1; i <= items->Length(); i++)
1330 if (!items->Value(i)->IsKind(STANDARD_TYPE(StepVisual_TessellatedItem)))
1336 Handle(StepRepr_HArray1OfRepresentationItem) itemsTess = new StepRepr_HArray1OfRepresentationItem(1, nC);
1337 Standard_Integer i = 1;
1338 for (Standard_Integer j = 1; j <= items->Length(); j++)
1340 if (!items->Value(j)->IsKind(STANDARD_TYPE(StepVisual_TessellatedItem)))
1342 itemsTess->SetValue(i++, items->Value(j));
1345 Handle(StepShape_ShapeRepresentation) shapeTessRepr = new StepVisual_TessellatedShapeRepresentation;
1346 shapeTessRepr->SetItems(itemsTess);
1347 STEPConstruct_UnitContext mk1;
1349 shapeTessRepr->SetContextOfItems(mk1.Value());
1350 shapeTessRepr->SetName(new TCollection_HAsciiString(""));
1352 aSeqBindRelation.Append(TransientResult(shapeTessRepr));
1354 if (!useExistingNMSSR)
1355 shapeRep->SetItems(items);
1357 // Add new representation item to the NMSSR's existing collection (ssv; 13.11.2010)
1358 Handle(StepRepr_HArray1OfRepresentationItem) oldItems = shapeRep->Items();
1359 Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1360 new StepRepr_HArray1OfRepresentationItem(1, oldItems->Length() + 1);
1361 Standard_Integer el = 1;
1362 for (Standard_Integer i = 1; i <= oldItems->Length(); i++)
1363 newItems->SetValue( el++, oldItems->Value(i) );
1364 newItems->SetValue( el, items->Value( items->Length() ) );
1365 shapeRep->SetItems(newItems);
1369 // init representation
1370 STEPConstruct_UnitContext mk;
1372 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1373 shapeRep->SetName (new TCollection_HAsciiString(""));
1375 // Create SDR (only once for non-manifold group)
1376 if (!useExistingNMSSR) {
1377 SDR0->SetUsedRepresentation (shapeRep);
1378 // create binder for SR and attach to it binder for RepItem (if exists)
1379 Handle(Transfer_Binder) resbind = TransientResult(shapeRep);
1380 binder = FP->Find(start);
1381 if ( ! binder.IsNull() ) {
1382 resbind->AddResult ( binder );
1383 FP->Rebind(start,resbind);
1384 //binder->AddResult ( resbind );
1387 for(Standard_Integer k = 1; k <= aSeqBindRelation.Length(); k++)
1388 resbind->AddResult(aSeqBindRelation.Value(k));
1390 // Add SDR for non-manifold topology in group mode 0 (ssv; 18.11.2010)
1391 if ( !aNMBinder.IsNull() )
1392 resbind->AddResult(aNMBinder);
1395 } else return FP->Find(start);
1399 //=======================================================================
1400 //function : TransferCompound
1401 // #### TRANSFER COMPOUND AS (SUB-)ASSEMBLY
1403 //=======================================================================
1405 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound
1406 (const Handle(Transfer_Finder)& start,
1407 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1408 const Handle(Transfer_FinderProcess)& FP,
1409 const Message_ProgressRange& theProgress)
1411 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1412 Handle(Transfer_Binder) binder;
1413 if (mapper.IsNull()) return binder;
1414 TopoDS_Shape theShape = mapper->Value();
1416 // Inspect non-manifold topology case (ssv; 10.11.2010)
1417 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
1418 Standard_Boolean isManifold;
1420 isManifold = IsManifoldShape(theShape);
1422 isManifold = Standard_True;
1424 // get a sequence of components (subshapes)
1425 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
1426 // Prepare a collection for non-manifold group of shapes
1427 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
1428 Standard_Boolean isSeparateVertices =
1429 (Interface_Static::IVal("write.step.vertex.mode") == 0);//bug 23950
1430 // PTV OCC725 17.09.2002 -- begin --
1431 Standard_Integer nbFreeVrtx = 0;
1432 TopoDS_Compound aCompOfVrtx;
1434 aB.MakeCompound(aCompOfVrtx);
1438 std::cout << "Exploding Solids to Shells if any..." << std::endl;
1441 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1442 TopoDS_Shape aSubShape = iter.Value();
1443 if (aSubShape.ShapeType() != TopAbs_VERTEX || !isSeparateVertices) {
1445 // Store non-manifold topology as shells (ssv; 10.11.2010)
1446 if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
1447 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
1448 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
1449 aSubShell.Closed(Standard_True);
1450 RepItemSeq->Append(aSubShell);
1451 NonManifoldGroup->Append(aSubShell);
1454 else if (!isManifold &&
1455 (aSubShape.ShapeType() == TopAbs_SHELL || aSubShape.ShapeType() == TopAbs_FACE))
1457 RepItemSeq->Append(aSubShape);
1458 NonManifoldGroup->Append(aSubShape);
1461 RepItemSeq->Append(aSubShape);
1465 aB.Add(aCompOfVrtx, iter.Value());
1469 RepItemSeq->Append (aCompOfVrtx);
1471 // PTV OCC725 17.09.2002 -- end --
1473 // Constitution : liste d axes, le premier est l origine, les suivants : 1
1475 Handle(StepShape_ShapeRepresentation) shapeRep =
1476 Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
1477 if ( shapeRep.IsNull() ) {
1478 shapeRep = new StepShape_ShapeRepresentation;
1479 SDR0->SetUsedRepresentation(shapeRep); // to be used by MakeItem
1481 binder = TransientResult(SDR0); // set SDR as first item in order to be found first (but not SDR of subshape!)
1482 binder->AddResult ( TransientResult(shapeRep) );
1484 // translate components
1485 Standard_Integer i, nbs = RepItemSeq->Length();
1486 Handle(TColStd_HSequenceOfTransient) ItemSeq = new TColStd_HSequenceOfTransient();
1487 ItemSeq->Append (myContext.GetDefaultAxis());
1488 myContext.NextLevel();
1489 Message_ProgressScope aPS(theProgress, NULL, nbs);
1490 for (i = 1; i <= nbs && aPS.More(); i++) {
1491 Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper (FP,RepItemSeq->Value(i));
1492 Handle(StepGeom_Axis2Placement3d) AX1;
1494 Handle(Transfer_Binder) bnd = TransferSubShape(subs, SDR0, AX1, FP, NonManifoldGroup, isManifold, aPS.Next());
1496 if (!AX1.IsNull()) ItemSeq->Append (AX1);
1497 // copy binders so as to have all roots in upper binder, but do not conflict
1498 while ( !bnd.IsNull() ) {
1499 Handle(Transfer_SimpleBinderOfTransient) bx =
1500 Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
1501 if ( !bx.IsNull() ) {
1502 binder->AddResult( TransientResult( bx->Result() ) );
1504 bnd = bnd->NextResult();
1507 myContext.PrevLevel();
1509 Standard_Integer nsub = ItemSeq->Length();
1510 Handle(StepRepr_HArray1OfRepresentationItem) items =
1511 new StepRepr_HArray1OfRepresentationItem(1,nsub);
1513 // initialize representation
1514 for (Standard_Integer rep = 1; rep <= nsub; rep++)
1515 items->SetValue(rep,GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep)));
1516 shapeRep->SetItems(items);
1517 Standard_Real Tol = UsedTolerance (mytoler,theShape);
1518 STEPConstruct_UnitContext mk;
1520 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1521 shapeRep->SetName (new TCollection_HAsciiString(""));
1524 // SDR0->SetUsedRepresentation (shapeRep);
1529 //=======================================================================
1530 //function : TransferSubShape
1532 //=======================================================================
1534 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape
1535 (const Handle(Transfer_Finder)& start,
1536 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1537 Handle(StepGeom_Axis2Placement3d)& AX1,
1538 const Handle(Transfer_FinderProcess)& FP,
1539 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
1540 const Standard_Boolean isManifold,
1541 const Message_ProgressRange& theProgress)
1543 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1544 if (mapper.IsNull()) return NullResult();
1545 TopoDS_Shape shape = mapper->Value();
1547 // SHAPE EN POSITION VENANT D UN ASSEMBLAGE
1548 // Il faut alors distinguer la transformation de la shape meme
1549 // laquelle est consideree a l origine, puis transferee
1550 // A part, un item decrivant une occurence en position est cree
1551 // SINON, la shape est prise et transferee telle quelle
1552 TopoDS_Shape sh0 = shape;
1554 if ( GroupMode() >0) {
1555 TopLoc_Location shloc = shape.Location();
1556 aLoc = shloc.Transformation();
1557 TopLoc_Location shident;
1558 sh0.Location (shident);
1559 mapper = TransferBRep::ShapeMapper(FP,sh0);
1560 mapper->SameAttributes (start);
1563 Handle(Transfer_Binder) resbind = FP->Find(mapper);
1564 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
1565 // Handle(StepShape_ShapeRepresentation) resultat;
1566 STEPConstruct_Part SDRTool;
1568 // Already SDR and SR available : take them as are
1569 Standard_Boolean iasdr = FP->GetTypedTransient
1570 (resbind,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation),sdr);
1571 if ( iasdr ) SDRTool.ReadSDR ( sdr );
1573 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
1574 sdr = SDRTool.SDRValue();
1576 // resultat = GetCasted(StepShape_ShapeRepresentation,sdr->UsedRepresentation());
1578 // if shape itself not yet translated, do it now
1579 //:abv 20.05.02: see comment in TransferShape(): added "! iasdr ||"
1580 Handle(Transfer_Binder) resprod = TransientResult(sdr); //KA - OCC7141(skl 10.11.2004)
1581 bool isJustTransferred = false;
1582 if ( ! iasdr || resbind.IsNull() ) {
1583 Handle(Transfer_Binder) resbind1 = TransferShape(mapper, sdr, FP, shapeGroup, isManifold, theProgress);
1584 if (resbind1.IsNull() || sdr->UsedRepresentation().IsNull())
1585 return Handle(Transfer_Binder)();
1587 Handle(Transfer_Binder) oldbind = FP->Find ( mapper );
1588 if ( ! oldbind.IsNull() && !resbind.IsNull()) resbind->AddResult ( oldbind );
1589 isJustTransferred = true;
1592 // A new resbind may have been produced
1593 // DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);
1594 // if (restrans.IsNull()) return resbind;
1595 // FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
1596 // sdr->SetUsedRepresentation(resultat); // to be used by MakeItem
1598 // make location for assembly placement
1599 GeomToStep_MakeAxis2Placement3d mkax (aLoc);
1600 Handle(StepGeom_Axis2Placement3d) AxLoc = mkax.Value();
1603 // create assembly structures (CDSR, NAUO etc.)
1604 STEPConstruct_Assembly mkitem;
1605 mkitem.Init (sdr,SDR0,myContext.GetDefaultAxis(),AxLoc);
1606 mkitem.MakeRelationship ();
1607 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink ( mkitem );
1609 // add roots corresponding to assembly and product structures to binder
1610 //Handle(Transfer_Binder) resprod = resbind; //KA - OCC7141(skl 10.11.2004)
1611 //KA: we need only the current subshape in resprod, since the binder is copied
1612 // in Transfershape which calls Transfersubshape [ OCC7141(skl 10.11.2004) ]
1614 resprod->AddResult (TransientResult (sdr));
1615 if (resprod != resbind)
1616 resbind->AddResult (TransientResult (sdr)); //KA - OCC7141(skl 10.11.2004)
1617 roots->Append ( myContext.GetRootsForPart ( SDRTool ) );
1619 for ( Standard_Integer i=1; i <= roots->Length(); i++ ) {
1620 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
1621 if (resprod != resbind)
1622 resbind->AddResult (TransientResult (roots->Value(i))); //KA - OCC7141(skl 10.11.2004)
1624 if (isJustTransferred)
1626 // We make CDSR of the current shape preceding CDSR of any subshapes,
1627 // therefore add resbind at the end.
1628 resprod->AddResult (resbind);
1629 FP->Bind (mapper, resprod);
1632 myContext.NextIndex();
1634 // abv 16.10.00: bind CDSR (et al) to located shape in order to be able to track instances
1635 if (mapper != start && aLoc.Form() != gp_Identity) {
1636 Handle(Transfer_Binder) bnd = FP->Find ( start );
1637 for ( Standard_Integer j=1; j <= roots->Length(); j++ )
1638 if ( bnd.IsNull() ) bnd = TransientResult ( roots->Value(j) );
1639 else bnd->AddResult ( TransientResult ( roots->Value(j) ) );
1640 FP->Bind ( start, bnd );