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 <BRepTools_Modifier.hxx>
23 #include <Geom_Curve.hxx>
24 #include <Geom_Line.hxx>
25 #include <Geom_Plane.hxx>
26 #include <Geom_Surface.hxx>
27 #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 <MoniTool_DataMapOfShapeTransient.hxx>
34 #include <OSD_Timer.hxx>
35 #include <ShapeAnalysis_ShapeTolerance.hxx>
36 #include <ShapeExtend_Explorer.hxx>
37 #include <ShapeProcess_ShapeContext.hxx>
38 #include <Standard_Type.hxx>
39 #include <StepBasic_ApplicationProtocolDefinition.hxx>
40 #include <StepBasic_HArray1OfProduct.hxx>
41 #include <STEPConstruct_AP203Context.hxx>
42 #include <STEPConstruct_Assembly.hxx>
43 #include <STEPConstruct_ContextTool.hxx>
44 #include <STEPConstruct_Part.hxx>
45 #include <STEPConstruct_UnitContext.hxx>
46 #include <STEPControl_ActorWrite.hxx>
47 #include <STEPControl_StepModelType.hxx>
48 #include <StepData_StepModel.hxx>
49 #include <StepGeom_Axis2Placement3d.hxx>
50 #include <StepGeom_GeomRepContextAndGlobUnitAssCtxAndGlobUncertaintyAssCtx.hxx>
51 #include <StepGeom_Point.hxx>
52 #include <StepRepr_GlobalUnitAssignedContext.hxx>
53 #include <StepRepr_HArray1OfRepresentationItem.hxx>
54 #include <StepRepr_PropertyDefinition.hxx>
55 #include <StepRepr_ShapeRepresentationRelationship.hxx>
56 #include <StepShape_AdvancedBrepShapeRepresentation.hxx>
57 #include <StepShape_BrepWithVoids.hxx>
58 #include <StepShape_FacetedBrep.hxx>
59 #include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
60 #include <StepShape_FacetedBrepShapeRepresentation.hxx>
61 #include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
62 #include <StepShape_GeometricCurveSet.hxx>
63 #include <StepShape_GeometricSetSelect.hxx>
64 #include <StepShape_HArray1OfGeometricSetSelect.hxx>
65 #include <StepShape_ManifoldSolidBrep.hxx>
66 #include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
67 #include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
68 #include <StepShape_ShapeDefinitionRepresentation.hxx>
69 #include <StepShape_ShapeRepresentation.hxx>
70 #include <StepShape_ShellBasedSurfaceModel.hxx>
71 #include <StepShape_TopologicalRepresentationItem.hxx>
72 #include <StepShape_VertexPoint.hxx>
73 #include <TCollection_HAsciiString.hxx>
74 #include <TColStd_HSequenceOfTransient.hxx>
76 #include <TopExp_Explorer.hxx>
78 #include <TopoDS_Compound.hxx>
79 #include <TopoDS_Iterator.hxx>
80 #include <TopoDS_Shape.hxx>
81 #include <TopoDS_Solid.hxx>
82 #include <TopoDSToStep.hxx>
83 #include <TopoDSToStep_Builder.hxx>
84 #include <TopoDSToStep_FacetedTool.hxx>
85 #include <TopoDSToStep_MakeBrepWithVoids.hxx>
86 #include <TopoDSToStep_MakeFacetedBrep.hxx>
87 #include <TopoDSToStep_MakeFacetedBrepAndBrepWithVoids.hxx>
88 #include <TopoDSToStep_MakeGeometricCurveSet.hxx>
89 #include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
90 #include <TopoDSToStep_MakeShellBasedSurfaceModel.hxx>
91 #include <TopoDSToStep_MakeStepVertex.hxx>
92 #include <TopoDSToStep_Tool.hxx>
93 #include <TopTools_HSequenceOfShape.hxx>
94 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
95 #include <TopTools_ListIteratorOfListOfShape.hxx>
96 #include <TopTools_ListOfShape.hxx>
97 #include <TopTools_MapOfShape.hxx>
98 #include <Transfer_Binder.hxx>
99 #include <Transfer_Finder.hxx>
100 #include <Transfer_FinderProcess.hxx>
101 #include <Transfer_SequenceOfBinder.hxx>
102 #include <Transfer_SimpleBinderOfTransient.hxx>
103 #include <Transfer_TransientProcess.hxx>
104 #include <TransferBRep.hxx>
105 #include <TransferBRep_ShapeMapper.hxx>
106 #include <UnitsMethods.hxx>
107 #include <XSAlgo.hxx>
108 #include <XSAlgo_AlgoContainer.hxx>
110 IMPLEMENT_STANDARD_RTTIEXT(STEPControl_ActorWrite,Transfer_ActorOfFinderProcess)
115 // Non-manifold topology processing (ssv; 10.11.2010)
116 // ============================================================================
117 // Function: DumpWhatIs
118 // Purpose: Use it in debug mode to dump your shapes
119 // ============================================================================
121 static void DumpWhatIs(const TopoDS_Shape& S) {
123 TopTools_MapOfShape aMapOfShape;
125 TopTools_ListOfShape aListOfShape;
126 aListOfShape.Append(S);
127 TopTools_ListIteratorOfListOfShape itL(aListOfShape);
128 Standard_Integer nbSolids = 0,
136 for( ; itL.More(); itL.Next() ) {
137 TopoDS_Iterator it( itL.Value() );
138 for ( ; it.More(); it.Next() ) {
139 TopoDS_Shape aSubShape = it.Value();
140 if ( !aMapOfShape.Add(aSubShape) )
142 aListOfShape.Append(aSubShape);
143 if (aSubShape.ShapeType() == TopAbs_SOLID)
145 if (aSubShape.ShapeType() == TopAbs_SHELL) {
146 if ( !aSubShape.Closed() )
150 if (aSubShape.ShapeType() == TopAbs_FACE)
152 if (aSubShape.ShapeType() == TopAbs_WIRE)
154 if (aSubShape.ShapeType() == TopAbs_EDGE)
156 if (aSubShape.ShapeType() == TopAbs_VERTEX)
161 std::cout << "//What is?// NB SOLIDS: " << nbSolids << std::endl;
162 std::cout << "//What is?// NB SHELLS: " << nbShells << std::endl;
163 std::cout << "//What is?// OPEN SHELLS: " << nbOpenShells << std::endl;
164 std::cout << "//What is?// CLOSED SHELLS: " << nbShells - nbOpenShells << std::endl;
165 std::cout << "//What is?// NB FACES: " << nbFaces << std::endl;
166 std::cout << "//What is?// NB WIRES: " << nbWires << std::endl;
167 std::cout << "//What is?// NB EDGES: " << nbEdges << std::endl;
168 std::cout << "//What is?// NB VERTEXES: " << nbVertexes << std::endl;
172 //=======================================================================
173 // Function : IsManifoldShape
174 // Purpose : Used to define whether the passed shape has manifold
176 //=======================================================================
178 static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
180 Standard_Boolean aResult = Standard_True;
182 // Do not check nested Compounds
183 TopoDS_Compound aDirectShapes;
184 BRep_Builder aBrepBuilder;
185 aBrepBuilder.MakeCompound(aDirectShapes);
187 TopoDS_Iterator anIt(theShape);
188 for ( ; anIt.More(); anIt.Next() ) {
189 TopoDS_Shape aDirectChild = anIt.Value();
190 if (aDirectChild.ShapeType() != TopAbs_COMPOUND)
191 aBrepBuilder.Add(aDirectShapes, aDirectChild);
195 DumpWhatIs(aDirectShapes);
198 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
199 TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
201 Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
203 std::cout << "Checking whether the topology passed is manifold..." << std::endl;
207 for (Standard_Integer i = 1; i <= aNbEdges; i++) {
208 TopoDS_Edge aCurrentEdge = TopoDS::Edge( aMapEdgeFaces.FindKey(i) );
209 if ( !BRep_Tool::Degenerated(aCurrentEdge) ) {
210 Standard_Integer aNbAncestors = aMapEdgeFaces.FindFromIndex(i).Extent();
211 if (aNbAncestors > 2) {
212 aResult = Standard_False;
219 std::cout << "Check result: "
220 << (aResult ? "TRUE" : "FALSE") << std::endl;
226 //=======================================================================
227 //function : STEPControl_ActorWrite
229 //=======================================================================
231 STEPControl_ActorWrite::STEPControl_ActorWrite ()
232 : mygroup (0) , mytoler (-1.)
234 SetMode(STEPControl_ShellBasedSurfaceModel);
237 //=======================================================================
238 //method: getNMSSRForGroup
239 //purpose: allows to get NMSSR (NON_MANIFOLD_SURFACE_SHAPE_REPRESENTATION)
240 // STEP's entity for the group of shells (!) passed
241 //=======================================================================
243 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::getNMSSRForGroup(const Handle(TopTools_HSequenceOfShape)& shapeGroup,
244 const Handle(Transfer_FinderProcess)& FP,
245 Standard_Boolean& isNMSSRCreated) const
247 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) aResult;
249 if ( !shapeGroup.IsNull() ) {
250 for (Standard_Integer i = 1; i <= shapeGroup->Length(); i++) {
251 TopoDS_Shape aCurrentShape = shapeGroup->Value(i);
252 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper(FP, aCurrentShape);
253 if ( FP->FindTypedTransient(mapper, STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation), aResult) )
258 if ( aResult.IsNull() ) {
260 std::cout << "\nNew NMSSR created" << std::endl;
262 aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
263 isNMSSRCreated = Standard_True;
266 std::cout << "\nExisting NMSSR is used" << std::endl;
268 isNMSSRCreated = Standard_False;
274 //=======================================================================
275 //function : mergeInfoForNM
276 //purpose : bind already written shared faces to STEP entity for non-manifold
277 //=======================================================================
278 void STEPControl_ActorWrite::mergeInfoForNM(const Handle(Transfer_FinderProcess)& theFP,
279 const Handle(Standard_Transient) &theInfo) const
281 Handle(ShapeProcess_ShapeContext) aContext = Handle(ShapeProcess_ShapeContext)::DownCast ( theInfo );
282 if ( aContext.IsNull() ) return;
284 const TopTools_DataMapOfShapeShape &aMap = aContext->Map();
285 TopTools_DataMapIteratorOfDataMapOfShapeShape aShapeShapeIt(aMap);
287 for ( ; aShapeShapeIt.More(); aShapeShapeIt.Next() ) {
288 TopoDS_Shape anOrig = aShapeShapeIt.Key(), aRes = aShapeShapeIt.Value();
289 if (anOrig.ShapeType() != TopAbs_FACE)
292 Handle(TransferBRep_ShapeMapper) anOrigMapper= TransferBRep::ShapeMapper ( theFP, anOrig);
293 Handle(Transfer_Binder) anOrigBinder = theFP->Find ( anOrigMapper );
294 if (anOrigBinder.IsNull())
297 Handle(TransferBRep_ShapeMapper) aResMapper = TransferBRep::ShapeMapper ( theFP, aRes );
298 theFP->Bind(aResMapper, anOrigBinder);
303 //=======================================================================
306 //=======================================================================
308 void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
311 case STEPControl_AsIs : ModeTrans() = 0; break;
312 case STEPControl_ManifoldSolidBrep : ModeTrans() = 3; break;
313 case STEPControl_BrepWithVoids : ModeTrans() = 5; break;
314 case STEPControl_FacetedBrep : ModeTrans() = 1; break;
315 case STEPControl_FacetedBrepAndBrepWithVoids : ModeTrans() = 6; break;
316 case STEPControl_ShellBasedSurfaceModel : ModeTrans() = 2; break;
317 case STEPControl_GeometricCurveSet : ModeTrans() = 4; break;
318 case STEPControl_Hybrid : ModeTrans() = 0; break; // PAS IMPLEMENTE !!
323 //=======================================================================
326 //=======================================================================
328 STEPControl_StepModelType STEPControl_ActorWrite::Mode () const
330 switch (themodetrans) {
331 case 0 : return STEPControl_AsIs;
332 case 1 : return STEPControl_FacetedBrep;
333 case 2 : return STEPControl_ShellBasedSurfaceModel;
334 case 3 : return STEPControl_ManifoldSolidBrep;
335 case 4 : return STEPControl_GeometricCurveSet;
336 case 5 : return STEPControl_BrepWithVoids;
337 case 6 : return STEPControl_FacetedBrepAndBrepWithVoids;
340 return STEPControl_AsIs;
343 //=======================================================================
344 //function : SetGroupMode
346 //=======================================================================
348 void STEPControl_ActorWrite::SetGroupMode (const Standard_Integer mode)
350 if (mode >= 0) mygroup = mode;
353 //=======================================================================
354 //function : GroupMode
356 //=======================================================================
358 Standard_Integer STEPControl_ActorWrite::GroupMode () const
363 //=======================================================================
364 //function : SetTolerance
366 //=======================================================================
368 void STEPControl_ActorWrite::SetTolerance (const Standard_Real Tol)
373 //=======================================================================
374 //function : Recognize
375 // ATTENTION, Recognize doit s aligner sur ce que Transfer sait faire
377 //=======================================================================
379 Standard_Boolean STEPControl_ActorWrite::Recognize (const Handle(Transfer_Finder)& start)
381 STEPControl_StepModelType mymode = Mode();
382 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
383 if (mapper.IsNull()) return Standard_False;
384 if (mymode == STEPControl_AsIs) return Standard_True;
386 Standard_Boolean yasolid = Standard_False, yashell = Standard_False,
387 yaface = Standard_False;
389 TopoDS_Shape theShape, aShape;
390 // theShape = TopoDSToStep::DirectFaces(mapper->Value());
391 theShape = mapper->Value(); // pour une reconnaissance c est bien assez
393 if (theShape.ShapeType() == TopAbs_COMPOUND) {
395 TopExp_Explorer SolidExp, ShellExp, FaceExp;
397 for (SolidExp.Init(theShape, TopAbs_SOLID);
398 SolidExp.More();SolidExp.Next()) yasolid = Standard_True;
399 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
400 ShellExp.More();ShellExp.Next()) yashell = Standard_True;
401 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
402 FaceExp.More();FaceExp.Next()) yaface = Standard_True;
404 else if (theShape.ShapeType() == TopAbs_SOLID) yasolid = Standard_True;
405 else if (theShape.ShapeType() == TopAbs_SHELL) yashell = Standard_True;
406 else if (theShape.ShapeType() == TopAbs_FACE) yaface = Standard_True;
407 else if (mymode != STEPControl_GeometricCurveSet) return Standard_False;
410 // Faceted : il est OBLIGATOIRE d avoir des surfaces support Plane et des
411 // courbes 3D Line (pcurves ignorees)
413 if (mymode == STEPControl_FacetedBrep || mymode == STEPControl_FacetedBrepAndBrepWithVoids) {
414 for (TopExp_Explorer ffac(theShape,TopAbs_FACE); ffac.More(); ffac.Next()) {
415 const TopoDS_Face& F = TopoDS::Face (ffac.Current());
416 TopLoc_Location locbid;
417 Handle(Geom_Surface) surf = BRep_Tool::Surface (F,locbid);
418 if (surf.IsNull() || !surf->IsKind(STANDARD_TYPE(Geom_Plane)) ) return Standard_False;
420 for (TopExp_Explorer fedg(theShape,TopAbs_EDGE); fedg.More(); fedg.Next()) {
421 const TopoDS_Edge& E = TopoDS::Edge (fedg.Current());
422 TopLoc_Location locbid; Standard_Real first,last;
423 Handle(Geom_Curve) curv = BRep_Tool::Curve (E,locbid,first,last);
424 if (curv.IsNull() || !curv->IsKind(STANDARD_TYPE(Geom_Line)) ) return Standard_False;
429 case STEPControl_ManifoldSolidBrep: return (yasolid || yashell);
430 case STEPControl_BrepWithVoids:
431 case STEPControl_FacetedBrep:
432 case STEPControl_FacetedBrepAndBrepWithVoids: return yasolid;
433 case STEPControl_ShellBasedSurfaceModel:
434 return (yasolid || yashell || yaface);
435 case STEPControl_GeometricCurveSet: return Standard_True; // tout OK
438 return Standard_False;
442 // ######## MAKE PRODUCT DATA + CONTEXT ########
444 //=======================================================================
445 //function : Transfer
447 //=======================================================================
449 Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_Finder)& start,
450 const Handle(Transfer_FinderProcess)& FP,
451 const Message_ProgressRange& theProgress)
453 XSAlgo::AlgoContainer()->PrepareForTransfer();
455 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
457 if (mapper.IsNull()) return NullResult();
458 TopoDS_Shape shape = mapper->Value();
461 Handle(StepData_StepModel) model = Handle(StepData_StepModel)::DownCast ( FP->Model() );
462 if ( ! model.IsNull() ) myContext.SetModel ( model ); //: abv 04.11.00: take APD from model
463 myContext.AddAPD ( Standard_False ); // update APD
464 myContext.SetLevel ( 1 ); // set assembly level to 1 (to ensure)
466 //:S4136: init UnitsMethods to reset angle unit factors (see TopoDSToStep)
467 Standard_Real lFactor = UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) );
468 lFactor /= UnitsMethods::GetCasCadeLengthUnit();
469 Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
470 UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
473 STEPConstruct_Part SDRTool;
474 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
475 Handle(StepShape_ShapeDefinitionRepresentation) sdr = SDRTool.SDRValue();
478 Handle(Transfer_Binder) resbind = TransferShape (mapper,sdr,FP, 0L, Standard_True, theProgress);
480 // Handle(StepShape_ShapeRepresentation) resultat;
481 // FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
482 // sdr->SetUsedRepresentation (resultat);
484 // create binder with all root entities produced from shape
485 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForPart ( SDRTool );
486 Handle(Transfer_Binder) resprod = TransientResult ( myContext.GetAPD() );
487 for ( Standard_Integer i=1; i <= roots->Length(); i++ )
488 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
489 resprod->AddResult(resbind);
492 //FP->Bind (mapper,resprod);
493 myContext.NextIndex();
497 //==========================================
499 static Standard_Real UsedTolerance (const Standard_Real mytoler,
500 const TopoDS_Shape& theShape)
503 // COMPUTING 3D TOLERANCE
504 // Either from Session, or Computed (Least,Average, or Greatest)
505 // Then given to TopoDSToStep_Tool
507 Standard_Real Tol = mytoler;
508 Standard_Integer tolmod = Interface_Static::IVal("write.precision.mode");
509 if (Tol <= 0 && tolmod == 2) Tol =
510 Interface_Static::RVal("write.precision.val");
512 ShapeAnalysis_ShapeTolerance stu;
513 Tol = stu.Tolerance (theShape,tolmod);
514 // Par defaut, on prend une tolerance moyenne, on elimine les aberrations
515 Tol = Interface_MSG::Intervalled (Tol * 1.5); // arrondi a 1 2 5 ...
517 if (Tol == 0) Tol = 1.e-07; // minimum ...
522 //=======================================================================
523 //function : IsAssembly
525 //=======================================================================
526 // if GroupMode is >1 downgrades all compounds having single subshape to that
529 Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
531 if ( ! GroupMode() || S.ShapeType() != TopAbs_COMPOUND ) return Standard_False;
532 // PTV 16.09.2002 OCC725 for storing compound of vertices
533 if (Interface_Static::IVal("write.step.vertex.mode") == 0) {//bug 23950
534 if (S.ShapeType() == TopAbs_COMPOUND ) {
535 Standard_Boolean IsOnlyVertices = Standard_True;
536 TopoDS_Iterator anItr( S );
537 for ( ; anItr.More(); anItr.Next() ) {
538 if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
539 IsOnlyVertices = Standard_False;
543 if ( IsOnlyVertices )
544 return Standard_False;
547 if ( GroupMode() ==1 ) return Standard_True;
548 TopoDS_Iterator it ( S );
549 if ( ! it.More() ) return Standard_False;
550 TopoDS_Shape shape = it.Value();
552 if ( it.More() ) return Standard_True;
554 return IsAssembly ( S );
557 //=======================================================================
558 //function : TransferShape
560 //=======================================================================
563 static void UpdateMap (const TopoDS_Shape &shape,
564 BRepTools_Modifier &M1,
565 BRepTools_Modifier &M2,
566 const Handle(Transfer_FinderProcess) &FinderProcess)
568 TopoDS_Shape S = M1.ModifiedShape ( shape );
569 S = M2.ModifiedShape ( S );
570 if ( S == shape ) return;
572 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess, S );
573 Handle(Transfer_Binder) binder = FinderProcess->Find ( mapper );
574 if ( ! binder.IsNull() ) {
575 mapper = TransferBRep::ShapeMapper ( FinderProcess, shape );
576 FinderProcess->Bind ( mapper, binder );
579 for ( TopoDS_Iterator it(shape); it.More(); it.Next() )
580 UpdateMap ( it.Value(), M1, M2, FinderProcess );
584 // PTV 16.09.2002 added for transfering vertices.
585 static Standard_Boolean transferVertex (const Handle(Transfer_FinderProcess)& FP,
586 Handle(StepShape_HArray1OfGeometricSetSelect)& aGSS,
587 const TopoDS_Shape& aShVrtx,
588 const Standard_Integer theNum)
590 Standard_Boolean IsDone = Standard_False;
591 MoniTool_DataMapOfShapeTransient aMap;
592 TopoDSToStep_Tool aTool(aMap, Standard_True);
593 TopoDSToStep_MakeStepVertex aMkVrtx ( TopoDS::Vertex(aShVrtx), aTool, FP );
595 if (!aMkVrtx.IsDone())
598 Handle(StepShape_VertexPoint) aVP =
599 Handle(StepShape_VertexPoint)::DownCast(aTool.Find(aShVrtx));
603 StepShape_GeometricSetSelect select;
604 select.SetValue(aVP->VertexGeometry());
605 // add current result
606 aGSS->SetValue( theNum, select );
607 IsDone = Standard_True;
612 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape
613 (const Handle(Transfer_Finder)& start,
614 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
615 const Handle(Transfer_FinderProcess)& FP,
616 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
617 const Standard_Boolean isManifold,
618 const Message_ProgressRange& theProgress)
620 STEPControl_StepModelType mymode = Mode();
621 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
622 Handle(Transfer_Binder) binder;
624 // Indicates whether to use an exising NMSSR to write items to (ss; 13.11.2010)
625 Standard_Boolean useExistingNMSSR = Standard_False;
627 if (mapper.IsNull()) return binder;
628 TopoDS_Shape theShape = mapper->Value();
630 if (theShape.IsNull()) return binder;
632 // INDIVIDUAL SHAPE ALREADY TRANSFERRED : RETURN IT !
633 binder = FP->Find(start);
634 if (!binder.IsNull()) { if (!binder->HasResult()) binder.Nullify(); }
635 if (!binder.IsNull()) {
636 //:abv 20.05.02: writing box & face from it (shared) in one compound
637 // as assembly - while face already translated, it should be
638 // re-translated to break sharing
640 std::cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << std::endl;
645 // MODE ASSEMBLY : if Compound, (sub-)assembly
646 if ( IsAssembly(theShape) )
647 return TransferCompound(start, SDR0, FP, theProgress);
649 Message_ProgressScope aPSRoot(theProgress, NULL, 2);
651 // [BEGIN] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
652 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
653 Handle(Transfer_Binder) aNMBinder;
654 if (isNMMode && !GroupMode() && theShape.ShapeType() == TopAbs_COMPOUND) {
655 TopoDS_Compound aNMCompound;
656 TopoDS_Compound aManifoldCompound;
657 BRep_Builder brepBuilder;
659 // Create empty Compounds
660 brepBuilder.MakeCompound(aManifoldCompound);
661 brepBuilder.MakeCompound(aNMCompound);
663 // Indicates whether there is only non-manifold topology detected
664 // (there is no manifold topology found in the Compound passed)
665 Standard_Boolean isOnlyNonManifold = Standard_False;
667 // Find a Compound containing non-manifold topology.
668 // NOTE: only one such Compound must exist in the entire Compound passed
669 if ( !IsManifoldShape(theShape) ) {
670 aNMCompound = TopoDS::Compound(theShape);
671 isOnlyNonManifold = Standard_True;
674 TopTools_ListOfShape aListOfShapes;
675 TopTools_ListOfShape aListOfManifoldShapes;
676 aListOfShapes.Append(theShape);
678 TopTools_ListIteratorOfListOfShape itL(aListOfShapes);
679 for ( ; itL.More(); itL.Next() ) {
680 TopoDS_Shape aParentShape = itL.Value();
681 TopoDS_Iterator it(aParentShape);
682 for ( ; it.More(); it.Next() ) {
683 TopoDS_Shape aSubShape = it.Value();
684 if (aSubShape.ShapeType() == TopAbs_COMPOUND && !IsManifoldShape(aSubShape) )
685 aNMCompound = TopoDS::Compound(aSubShape);
686 else if (aSubShape.ShapeType() == TopAbs_COMPOUND)
687 aListOfShapes.Append(aSubShape);
689 aListOfManifoldShapes.Append(aSubShape);
693 // Group manifold topology together.
694 // NOTE: there is no sense that initial Compound structure was lost as
695 // group mode is set to 0 (no Assemblies are mapped)
696 for ( itL.Initialize(aListOfManifoldShapes); itL.More(); itL.Next() ) {
697 TopoDS_Shape aCurrentManiShape = itL.Value();
698 brepBuilder.Add(aManifoldCompound, aCurrentManiShape);
703 // Process only manifold topology in the current TransferShape invocation.
704 // Invoke TransferShape for non-manifold topology separately (see below)
705 theShape = aManifoldCompound;
707 // List of items to transfer
708 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
709 // Non-manifold group to pass into TransferShape with each shape from RepItemSeq
710 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
712 // Transfer Solids to closed Shells. Prepare RepItemSeq & NonManifoldGroup
713 for ( TopoDS_Iterator iter(aNMCompound); iter.More(); iter.Next() ) {
714 TopoDS_Shape aSubShape = iter.Value();
715 if (aSubShape.ShapeType() == TopAbs_SOLID) {
716 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
717 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
718 aSubShell.Closed(Standard_True);
719 RepItemSeq->Append(aSubShell);
720 NonManifoldGroup->Append(aSubShell);
723 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
724 RepItemSeq->Append(aSubShape);
725 NonManifoldGroup->Append(aSubShape);
728 RepItemSeq->Append( iter.Value() );
731 Standard_Integer aNMItemsNb = RepItemSeq->Length();
733 // In case of pure manifold topology do nothing; theShape is processed as usual (see below)
734 if (aNMItemsNb > 0) {
736 // Prepare SDR for non-manifold group. This SDR will be linked to NMSSR by means
737 // of TransferShape invocation. SDR is not created if there is no any manifold
738 // topology in the passed Compound. If topology is pure non-manifold, SDR0 (passed)
740 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
741 if (isOnlyNonManifold)
744 STEPConstruct_Part SDRTool;
745 SDRTool.MakeSDR( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
746 sdr = SDRTool.SDRValue();
749 aNMBinder = TransientResult(sdr);
751 // Complete SDR with shape representations.
752 // NOTE: aNMBinder is connected now with this SDR. It will be added to the resulting
753 // binder in the end of this invocation of TransferShape
754 Message_ProgressScope aPS (aPSRoot.Next(), NULL, aNMItemsNb);
755 for (Standard_Integer i = 1; i <= aNMItemsNb && aPS.More(); i++) {
756 Handle(TransferBRep_ShapeMapper) aMapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
757 TransferShape(aMapper, sdr, FP, NonManifoldGroup, Standard_False, aPS.Next());
760 // Nothing else needed for pure non-manifold topology, return
761 if (isOnlyNonManifold)
767 // [END] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
769 if (aPSRoot.UserBreak())
770 return Handle(Transfer_Binder)();
772 // create a list of items to translate
773 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
775 Standard_Boolean isSeparateVertices =
776 Interface_Static::IVal("write.step.vertex.mode") == 0;//bug 23950
777 // PTV 16.09.2002 OCC725 separate shape from solo vertices.
778 Standard_Boolean isOnlyVertices = Standard_False;
779 if (theShape.ShapeType() == TopAbs_COMPOUND) {
780 Standard_Integer countVrtx = 0;
781 Standard_Integer countSh = 0;
782 TopoDS_Compound aNewShape, aCompOfVrtx;
784 aB.MakeCompound(aNewShape);
785 aB.MakeCompound(aCompOfVrtx);
786 TopoDS_Iterator anCompIt(theShape);
787 if (isSeparateVertices) {
788 for (; anCompIt.More(); anCompIt.Next()) {
789 TopoDS_Shape aCurSh = anCompIt.Value();
790 if (aCurSh.ShapeType() != TopAbs_VERTEX) {
791 aB.Add(aNewShape, aCurSh);
795 aB.Add(aCompOfVrtx, aCurSh);
799 // replace the shapes
801 theShape = aNewShape;
803 RepItemSeq->Append(aCompOfVrtx);
805 isOnlyVertices = Standard_True;
809 if (theShape.ShapeType() == TopAbs_COMPOUND) {
810 TopExp_Explorer SolidExp, ShellExp, FaceExp;
811 if (mymode != STEPControl_GeometricCurveSet) {
812 for (SolidExp.Init(theShape, TopAbs_SOLID);
813 SolidExp.More();SolidExp.Next()) {
814 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
816 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
817 ShellExp.More();ShellExp.Next()) {
818 RepItemSeq->Append(TopoDS::Shell(ShellExp.Current()));
821 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
822 FaceExp.More();FaceExp.Next()) {
823 RepItemSeq->Append(TopoDS::Face(FaceExp.Current()));
828 RepItemSeq->Append(theShape); //:j1
830 if(mymode == STEPControl_AsIs) {
831 TopExp_Explorer WireExp, EdgeExp;
832 for (WireExp.Init(theShape, TopAbs_WIRE, TopAbs_FACE);
833 WireExp.More();WireExp.Next())
834 RepItemSeq->Append(TopoDS::Wire(WireExp.Current()));
835 for (EdgeExp.Init(theShape, TopAbs_EDGE, TopAbs_WIRE);
836 EdgeExp.More();EdgeExp.Next())
837 RepItemSeq->Append(TopoDS::Edge(EdgeExp.Current()));
841 else if (theShape.ShapeType() == TopAbs_SOLID) {
842 RepItemSeq->Append(TopoDS::Solid(theShape));
844 else if (theShape.ShapeType() == TopAbs_SHELL) {
845 RepItemSeq->Append(TopoDS::Shell(theShape));
847 else if (theShape.ShapeType() == TopAbs_FACE) {
848 RepItemSeq->Append(TopoDS::Face(theShape));
850 else if (theShape.ShapeType() == TopAbs_COMPSOLID) {
851 FP->AddWarning(start,"NonManifold COMPSOLID was translated like a set of SOLIDs");
852 if ( GroupMode() > 0)
853 return TransferCompound(start, SDR0, FP, aPSRoot.Next());
855 TopExp_Explorer SolidExp;
856 for (SolidExp.Init(theShape, TopAbs_SOLID);
857 SolidExp.More();SolidExp.Next()) {
858 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
863 else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
864 FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
867 else RepItemSeq->Append (theShape);
869 // COMPUTING 3D TOLERANCE
870 // Either from Session, or Computed (Least,Average, or Greatest)
871 // Then given to TopoDSToStep_Tool
872 Standard_Real Tol = UsedTolerance (mytoler,theShape);
874 // Create a STEP-Entity for each TopoDS_Shape
875 // according to the current StepModelMode
877 Standard_Integer nbs = RepItemSeq->Length();
878 Handle(TColStd_HSequenceOfTransient) ItemSeq =
879 new TColStd_HSequenceOfTransient();
881 //ptv 10.11.00: allow to write empty Compound: if (GroupMode() >0)
882 ItemSeq->Append (myContext.GetDefaultAxis());
883 STEPControl_StepModelType trmode = mymode;
884 Message_ProgressScope aPS (aPSRoot.Next(), NULL, nbs);
885 for (Standard_Integer i = 1; i <= nbs && aPS.More(); i++) {
886 TopoDS_Shape xShape = RepItemSeq->Value(i);
888 if(mymode == STEPControl_AsIs) {
889 switch(xShape.ShapeType()) {
890 case TopAbs_SOLID : trmode = STEPControl_ManifoldSolidBrep;break;
891 case TopAbs_SHELL : trmode = STEPControl_ShellBasedSurfaceModel; break;
892 case TopAbs_FACE : trmode = STEPControl_ShellBasedSurfaceModel;break;
893 default : trmode =STEPControl_GeometricCurveSet; break;
896 //:abv 24Jan99 CAX-IF TRJ3: expanded Shape Processing
897 // TopoDS_Shape aShape = xShape;
898 // eliminate conical surfaces with negative semiangles
899 // Handle(TopoDSToStep_ConicalSurfModif) CSM = new TopoDSToStep_ConicalSurfModif();
900 // BRepTools_Modifier CSMT(aShape,CSM);
901 // if ( CSMT.IsDone() ) aShape = CSMT.ModifiedShape ( aShape );
902 // // eliminate indirect elementary surfaces
903 // Handle(TopoDSToStep_DirectModification) DM = new TopoDSToStep_DirectModification();
904 // BRepTools_Modifier DMT(aShape,DM);
905 // if ( DMT.IsDone() ) aShape = DMT.ModifiedShape ( aShape );
906 //// aShape = TopoDSToStep::DirectFaces(xShape);
907 Handle(Standard_Transient) info;
908 Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
910 Message_ProgressScope aPS1 (aPS.Next(), NULL, 2);
913 aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol,
914 "write.step.resource.name",
915 "write.step.sequence", info,
917 if (aPS1.UserBreak())
918 return Handle(Transfer_Binder)();
921 mergeInfoForNM(FP, info);
924 // create a STEP entity corresponding to shape
925 Handle(StepGeom_GeometricRepresentationItem) item;
928 case STEPControl_ManifoldSolidBrep:
930 if (aShape.ShapeType() == TopAbs_SOLID) {
931 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
933 //:d6 abv 13 Mar 98: if solid has more than 1 shell,
934 // try to treat it as solid with voids
935 Standard_Integer nbShells = 0;
936 for ( TopoDS_Iterator It ( aSolid ); It.More(); It.Next() )
937 if (It.Value().ShapeType() == TopAbs_SHELL) nbShells++;
939 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP, aPS1.Next());
940 MkBRepWithVoids.Tolerance() = Tol;
941 if (MkBRepWithVoids.IsDone()) {
942 item = MkBRepWithVoids.Value();
944 else nbShells = 1; //smth went wrong; let it will be just Manifold
946 if ( nbShells ==1 ) {
948 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aSolid,FP, aPS1.Next());
949 MkManifoldSolidBrep.Tolerance() = Tol;
950 if (MkManifoldSolidBrep.IsDone()) {
951 item = MkManifoldSolidBrep.Value();
955 else if (aShape.ShapeType() == TopAbs_SHELL) {
956 TopoDS_Shell aShell = TopoDS::Shell(aShape);
957 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aShell,FP, aPS1.Next());
958 MkManifoldSolidBrep.Tolerance() = Tol;
959 if (MkManifoldSolidBrep.IsDone()) {
960 item = MkManifoldSolidBrep.Value();
965 case STEPControl_BrepWithVoids:
967 if (aShape.ShapeType() == TopAbs_SOLID) {
968 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
969 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP, aPS1.Next());
970 MkBRepWithVoids.Tolerance() = Tol;
971 if (MkBRepWithVoids.IsDone()) {
972 item = MkBRepWithVoids.Value();
977 case STEPControl_FacetedBrep:
979 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
980 if (facErr != TopoDSToStep_FacetedDone) {
981 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
982 if (facErr == TopoDSToStep_SurfaceNotPlane) {
983 FP->AddFail(start,"-- The TopoDS_Face is not plane");
985 else if (facErr == TopoDSToStep_PCurveNotLinear) {
986 FP->AddFail(start,"-- The Face contains non linear PCurves");
990 if (aShape.ShapeType() == TopAbs_SOLID) {
991 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
992 TopoDSToStep_MakeFacetedBrep MkFacetedBrep(aSolid,FP, aPS1.Next());
993 MkFacetedBrep.Tolerance() = Tol;
994 if (MkFacetedBrep.IsDone()) {
995 item = MkFacetedBrep.Value();
1000 case STEPControl_FacetedBrepAndBrepWithVoids:
1002 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
1003 if (facErr != TopoDSToStep_FacetedDone) {
1004 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
1005 if (facErr == TopoDSToStep_SurfaceNotPlane) {
1006 FP->AddFail(start,"-- The TopoDS_Face is not plane");
1008 else if (facErr == TopoDSToStep_PCurveNotLinear) {
1009 FP->AddFail(start,"-- The Face contains non linear PCurves");
1013 if (aShape.ShapeType() == TopAbs_SOLID) {
1014 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1015 TopoDSToStep_MakeFacetedBrepAndBrepWithVoids
1016 MkFacetedBrepAndBrepWithVoids(aSolid,FP, aPS1.Next());
1017 MkFacetedBrepAndBrepWithVoids.Tolerance() = Tol;
1018 if (MkFacetedBrepAndBrepWithVoids.IsDone()) {
1019 item = MkFacetedBrepAndBrepWithVoids.Value();
1024 case STEPControl_ShellBasedSurfaceModel:
1026 if (aShape.ShapeType() == TopAbs_SOLID) {
1027 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1028 TopoDSToStep_MakeShellBasedSurfaceModel
1029 MkShellBasedSurfaceModel(aSolid, FP, aPS1.Next());
1030 MkShellBasedSurfaceModel.Tolerance() = Tol;
1031 if (MkShellBasedSurfaceModel.IsDone()) {
1032 item = MkShellBasedSurfaceModel.Value();
1035 else if (aShape.ShapeType() == TopAbs_SHELL) {
1036 TopoDS_Shell aShell = TopoDS::Shell(aShape);
1037 // Non-manifold topology is stored via NMSSR containing series of SBSM (ssv; 13.11.2010)
1038 TopoDSToStep_MakeShellBasedSurfaceModel MkShellBasedSurfaceModel(aShell, FP, aPS1.Next());
1039 MkShellBasedSurfaceModel.Tolerance() = Tol;
1040 if (MkShellBasedSurfaceModel.IsDone()) {
1041 item = MkShellBasedSurfaceModel.Value();
1044 else if (aShape.ShapeType() == TopAbs_FACE) {
1045 TopoDS_Face aFace = TopoDS::Face(aShape);
1046 TopoDSToStep_MakeShellBasedSurfaceModel
1047 MkShellBasedSurfaceModel(aFace, FP, aPS1.Next());
1048 MkShellBasedSurfaceModel.Tolerance() = Tol;
1049 if (MkShellBasedSurfaceModel.IsDone()) {
1050 item = MkShellBasedSurfaceModel.Value();
1055 case STEPControl_GeometricCurveSet:
1057 TopoDSToStep_MakeGeometricCurveSet MkGeometricCurveSet(aShape,FP);
1058 MkGeometricCurveSet.Tolerance() = Tol;
1059 if (MkGeometricCurveSet.IsDone()) {
1060 item = MkGeometricCurveSet.Value();
1062 // PTV 22.08.2002 OCC609 ------------------------- begin --------------------
1063 // modified by PTV 16.09.2002 OCC725
1064 else if (aShape.ShapeType() == TopAbs_COMPOUND ||
1065 aShape.ShapeType() == TopAbs_VERTEX) {
1066 // it is compund with solo vertices.
1067 Standard_Integer aNbVrtx = 0;
1068 Standard_Integer curNb = 0;
1069 TopExp_Explorer anExp (aShape, TopAbs_VERTEX);
1070 for ( ; anExp.More(); anExp.Next() ) {
1071 if ( anExp.Current().ShapeType() != TopAbs_VERTEX )
1076 // create new geometric curve set for all vertices
1077 Handle(StepShape_HArray1OfGeometricSetSelect) aGSS =
1078 new StepShape_HArray1OfGeometricSetSelect(1,aNbVrtx);
1079 Handle(TCollection_HAsciiString) empty = new TCollection_HAsciiString("");
1080 Handle(StepShape_GeometricCurveSet) aGCSet =
1081 new StepShape_GeometricCurveSet;
1082 aGCSet->SetName(empty);
1083 // iterates on compound with vertices and trances each vertex
1084 for ( anExp.ReInit() ; anExp.More(); anExp.Next() ) {
1085 TopoDS_Shape aVertex = anExp.Current();
1086 if ( aVertex.ShapeType() != TopAbs_VERTEX )
1089 transferVertex (FP, aGSS, aVertex, curNb);
1090 } // end of iteration on compound with vertices.
1091 aGCSet->SetElements(aGSS);
1093 } // end of check that number of vertices is not null
1095 // PTV 22.08.2002 OCC609------------------------- end --------------------
1100 if ( item.IsNull() ) continue;
1102 // add resulting item to the FP
1103 ItemSeq->Append(item);
1104 Handle(TransferBRep_ShapeMapper) submapper;
1105 if ( xShape.IsSame ( mapper->Value() ) )
1106 submapper = Handle(TransferBRep_ShapeMapper)::DownCast ( start );
1107 if ( submapper.IsNull() ) submapper = TransferBRep::ShapeMapper (FP,xShape);
1108 Handle(Transfer_Binder) subbind = FP->Find ( submapper );
1109 if ( subbind.IsNull() ) {
1110 subbind = TransientResult ( item );
1111 FP->Bind ( submapper, subbind );
1113 else subbind->AddResult ( TransientResult ( item ) );
1115 //:abv 24Jan99 CAX-IF TRJ3: Update FinderProcess map to take into account shape processing
1116 // UpdateMap ( xShape, CSMT, DMT, FP );
1117 XSAlgo::AlgoContainer()->MergeTransferInfo(FP, info);
1120 // - Make Shape Representation
1121 Standard_Integer nCc1 = ItemSeq->Length();
1123 FP->AddFail(start,"The Shape has not the appropriate type");
1126 Handle(StepShape_ShapeRepresentation) shapeRep;
1127 if ( theShape.ShapeType() == TopAbs_SHAPE ) { // for external references
1128 shapeRep = new StepShape_ShapeRepresentation;
1132 case STEPControl_ManifoldSolidBrep:
1133 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1135 case STEPControl_FacetedBrep:
1136 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1138 // NOTE: STEPControl_AsIs mode is normally used to transfer non-manifold topology.
1139 // However, as ShellBasedSurfaceModel is used in non-manifold processing
1140 // internally, STEPControl_ShellBasedSurfaceModel is also adjusted to
1141 // be able to work with non-manifold cases
1142 case STEPControl_ShellBasedSurfaceModel:
1144 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1146 Standard_Boolean isNewNMSSRCreated;
1147 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1148 useExistingNMSSR = !isNewNMSSRCreated;
1151 case STEPControl_GeometricCurveSet:
1152 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1154 case STEPControl_AsIs :
1157 if(trmode == STEPControl_ManifoldSolidBrep)
1158 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1159 else if(trmode == STEPControl_ShellBasedSurfaceModel)
1160 // Process non-manifold topology separately (ssv; 13.11.2010)
1162 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1164 Standard_Boolean isNewNMSSRCreated;
1165 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1166 useExistingNMSSR = !isNewNMSSRCreated;
1168 else if(trmode == STEPControl_GeometricCurveSet)
1169 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1170 else if(trmode ==STEPControl_FacetedBrep)
1171 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1173 else shapeRep = new StepShape_ShapeRepresentation;
1179 if(shapeRep.IsNull()) {
1180 Handle(Transfer_Binder) resb;
1184 Handle(StepRepr_HArray1OfRepresentationItem) items =
1185 new StepRepr_HArray1OfRepresentationItem(1,nCc1);
1187 for (Standard_Integer rep = 1; rep <= nCc1; rep++) {
1188 Handle(StepRepr_RepresentationItem) repit =
1189 GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep));
1190 items->SetValue(rep,repit);
1192 Standard_Integer ap = Interface_Static::IVal("write.step.schema");
1193 Transfer_SequenceOfBinder aSeqBindRelation;
1194 if(ap == 3 && nbs > 1) {
1195 Standard_Integer j = 1;
1196 if(items->Value(j)->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d))) {
1197 Handle(StepRepr_HArray1OfRepresentationItem) axis =
1198 new StepRepr_HArray1OfRepresentationItem(1,1);
1199 axis->SetValue(1,items->Value(j++));
1200 shapeRep->SetItems(axis);
1202 for (; j <= items->Length(); j++) {
1204 Handle(StepShape_ShapeRepresentation) ShapeRepr1;
1205 if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep)))
1206 ShapeRepr1 = new StepShape_AdvancedBrepShapeRepresentation;
1207 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel)))
1208 ShapeRepr1 = new StepShape_ManifoldSurfaceShapeRepresentation;
1209 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_GeometricCurveSet)))
1210 ShapeRepr1 = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1211 else if (items->Value(j)->IsKind(STANDARD_TYPE(StepShape_FacetedBrep)))
1212 ShapeRepr1 = new StepShape_FacetedBrepShapeRepresentation;
1213 else ShapeRepr1 = new StepShape_ShapeRepresentation;
1215 Handle(StepRepr_HArray1OfRepresentationItem) repr1 = new StepRepr_HArray1OfRepresentationItem(1,2);
1216 repr1->SetValue(1,myContext.GetDefaultAxis());
1217 repr1->SetValue(2,items->Value(j));
1218 ShapeRepr1->SetItems(repr1);
1219 STEPConstruct_UnitContext mk1;
1221 ShapeRepr1->SetContextOfItems(mk1.Value()); // la tolerance, voir au debut
1222 ShapeRepr1->SetName (new TCollection_HAsciiString(""));
1224 Handle(StepRepr_ShapeRepresentationRelationship) aShapeRel = new StepRepr_ShapeRepresentationRelationship;
1225 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
1226 Handle(TCollection_HAsciiString) aDescr = new TCollection_HAsciiString("");
1227 aShapeRel->SetName(aName);
1228 aShapeRel->SetDescription(aDescr);
1229 aShapeRel->SetRep2(shapeRep);
1230 aShapeRel->SetRep1(ShapeRepr1);
1232 aSeqBindRelation.Append(TransientResult (aShapeRel));
1236 if (!useExistingNMSSR)
1237 shapeRep->SetItems(items);
1239 // Add new representation item to the NMSSR's existing collection (ssv; 13.11.2010)
1240 Handle(StepRepr_HArray1OfRepresentationItem) oldItems = shapeRep->Items();
1241 Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1242 new StepRepr_HArray1OfRepresentationItem(1, oldItems->Length() + 1);
1243 Standard_Integer el = 1;
1244 for (Standard_Integer i = 1; i <= oldItems->Length(); i++)
1245 newItems->SetValue( el++, oldItems->Value(i) );
1246 newItems->SetValue( el, items->Value( items->Length() ) );
1247 shapeRep->SetItems(newItems);
1251 // init representation
1252 STEPConstruct_UnitContext mk;
1254 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1255 shapeRep->SetName (new TCollection_HAsciiString(""));
1257 // Create SDR (only once for non-manifold group)
1258 if (!useExistingNMSSR) {
1259 SDR0->SetUsedRepresentation (shapeRep);
1260 // create binder for SR and attach to it binder for RepItem (if exists)
1261 Handle(Transfer_Binder) resbind = TransientResult(shapeRep);
1262 binder = FP->Find(start);
1263 if ( ! binder.IsNull() ) {
1264 resbind->AddResult ( binder );
1265 FP->Rebind(start,resbind);
1266 //binder->AddResult ( resbind );
1269 for(Standard_Integer k = 1; k <= aSeqBindRelation.Length(); k++)
1270 resbind->AddResult(aSeqBindRelation.Value(k));
1272 // Add SDR for non-manifold topology in group mode 0 (ssv; 18.11.2010)
1273 if ( !aNMBinder.IsNull() )
1274 resbind->AddResult(aNMBinder);
1277 } else return FP->Find(start);
1281 //=======================================================================
1282 //function : TransferCompound
1283 // #### TRANSFER COMPOUND AS (SUB-)ASSEMBLY
1285 //=======================================================================
1287 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound
1288 (const Handle(Transfer_Finder)& start,
1289 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1290 const Handle(Transfer_FinderProcess)& FP,
1291 const Message_ProgressRange& theProgress)
1293 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1294 Handle(Transfer_Binder) binder;
1295 if (mapper.IsNull()) return binder;
1296 TopoDS_Shape theShape = mapper->Value();
1298 // Inspect non-manifold topology case (ssv; 10.11.2010)
1299 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold") != 0;
1300 Standard_Boolean isManifold;
1302 isManifold = IsManifoldShape(theShape);
1304 isManifold = Standard_True;
1306 // get a sequence of components (subshapes)
1307 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
1308 // Prepare a collection for non-manifold group of shapes
1309 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
1310 Standard_Boolean isSeparateVertices =
1311 (Interface_Static::IVal("write.step.vertex.mode") == 0);//bug 23950
1312 // PTV OCC725 17.09.2002 -- begin --
1313 Standard_Integer nbFreeVrtx = 0;
1314 TopoDS_Compound aCompOfVrtx;
1316 aB.MakeCompound(aCompOfVrtx);
1320 std::cout << "Exploding Solids to Shells if any..." << std::endl;
1323 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1324 TopoDS_Shape aSubShape = iter.Value();
1325 if (aSubShape.ShapeType() != TopAbs_VERTEX || !isSeparateVertices) {
1327 // Store non-manifold topology as shells (ssv; 10.11.2010)
1328 if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
1329 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
1330 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
1331 aSubShell.Closed(Standard_True);
1332 RepItemSeq->Append(aSubShell);
1333 NonManifoldGroup->Append(aSubShell);
1336 else if (!isManifold &&
1337 (aSubShape.ShapeType() == TopAbs_SHELL || aSubShape.ShapeType() == TopAbs_FACE))
1339 RepItemSeq->Append(aSubShape);
1340 NonManifoldGroup->Append(aSubShape);
1343 RepItemSeq->Append(aSubShape);
1347 aB.Add(aCompOfVrtx, iter.Value());
1351 RepItemSeq->Append (aCompOfVrtx);
1353 // PTV OCC725 17.09.2002 -- end --
1355 // Constitution : liste d axes, le premier est l origine, les suivants : 1
1357 Handle(StepShape_ShapeRepresentation) shapeRep =
1358 Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
1359 if ( shapeRep.IsNull() ) {
1360 shapeRep = new StepShape_ShapeRepresentation;
1361 SDR0->SetUsedRepresentation(shapeRep); // to be used by MakeItem
1363 binder = TransientResult(SDR0); // set SDR as first item in order to be found first (but not SDR of subshape!)
1364 binder->AddResult ( TransientResult(shapeRep) );
1366 // translate components
1367 Standard_Integer i, nbs = RepItemSeq->Length();
1368 Handle(TColStd_HSequenceOfTransient) ItemSeq = new TColStd_HSequenceOfTransient();
1369 ItemSeq->Append (myContext.GetDefaultAxis());
1370 myContext.NextLevel();
1371 Message_ProgressScope aPS(theProgress, NULL, nbs);
1372 for (i = 1; i <= nbs && aPS.More(); i++) {
1373 Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper (FP,RepItemSeq->Value(i));
1374 Handle(StepGeom_Axis2Placement3d) AX1;
1376 Handle(Transfer_Binder) bnd = TransferSubShape(subs, SDR0, AX1, FP, NonManifoldGroup, isManifold, aPS.Next());
1378 if (!AX1.IsNull()) ItemSeq->Append (AX1);
1379 // copy binders so as to have all roots in upper binder, but do not conflict
1380 while ( !bnd.IsNull() ) {
1381 Handle(Transfer_SimpleBinderOfTransient) bx =
1382 Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
1383 if ( !bx.IsNull() ) {
1384 // Single SDR is created for a non-manifold group (ssv: 12.11.2010)
1385 if (!isManifold && i > 1)
1388 binder->AddResult( TransientResult( bx->Result() ) );
1390 bnd = bnd->NextResult();
1393 myContext.PrevLevel();
1395 Standard_Integer nsub = ItemSeq->Length();
1396 Handle(StepRepr_HArray1OfRepresentationItem) items =
1397 new StepRepr_HArray1OfRepresentationItem(1,nsub);
1399 // initialize representation
1400 for (Standard_Integer rep = 1; rep <= nsub; rep++)
1401 items->SetValue(rep,GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep)));
1402 shapeRep->SetItems(items);
1403 Standard_Real Tol = UsedTolerance (mytoler,theShape);
1404 STEPConstruct_UnitContext mk;
1406 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1407 shapeRep->SetName (new TCollection_HAsciiString(""));
1410 // SDR0->SetUsedRepresentation (shapeRep);
1415 //=======================================================================
1416 //function : TransferSubShape
1418 //=======================================================================
1420 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape
1421 (const Handle(Transfer_Finder)& start,
1422 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1423 Handle(StepGeom_Axis2Placement3d)& AX1,
1424 const Handle(Transfer_FinderProcess)& FP,
1425 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
1426 const Standard_Boolean isManifold,
1427 const Message_ProgressRange& theProgress)
1429 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1430 if (mapper.IsNull()) return NullResult();
1431 TopoDS_Shape shape = mapper->Value();
1433 // SHAPE EN POSITION VENANT D UN ASSEMBLAGE
1434 // Il faut alors distinguer la transformation de la shape meme
1435 // laquelle est consideree a l origine, puis transferee
1436 // A part, un item decrivant une occurence en position est cree
1437 // SINON, la shape est prise et transferee telle quelle
1438 TopoDS_Shape sh0 = shape;
1440 if ( GroupMode() >0) {
1441 TopLoc_Location shloc = shape.Location();
1442 aLoc = shloc.Transformation();
1443 TopLoc_Location shident;
1444 sh0.Location (shident);
1445 mapper = TransferBRep::ShapeMapper(FP,sh0);
1446 mapper->SameAttributes (start);
1449 Handle(Transfer_Binder) resbind = FP->Find(mapper);
1450 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
1451 // Handle(StepShape_ShapeRepresentation) resultat;
1452 STEPConstruct_Part SDRTool;
1454 // Already SDR and SR available : take them as are
1455 Standard_Boolean iasdr = FP->GetTypedTransient
1456 (resbind,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation),sdr);
1457 if ( iasdr ) SDRTool.ReadSDR ( sdr );
1459 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
1460 sdr = SDRTool.SDRValue();
1462 // resultat = GetCasted(StepShape_ShapeRepresentation,sdr->UsedRepresentation());
1464 // if shape itself not yet translated, do it now
1465 //:abv 20.05.02: see comment in TransferShape(): added "! iasdr ||"
1466 Handle(Transfer_Binder) resprod = TransientResult(sdr); //KA - OCC7141(skl 10.11.2004)
1467 if ( ! iasdr || resbind.IsNull() ) {
1468 resbind = TransferShape(mapper, sdr, FP, shapeGroup, isManifold, theProgress);
1469 Handle(Transfer_Binder) oldbind = FP->Find ( mapper );
1470 if ( ! oldbind.IsNull() && !resbind.IsNull()) resbind->AddResult ( oldbind );
1471 FP->Bind (mapper,resbind);
1472 resprod=resbind; //KA - OCC7141(skl 10.11.2004)
1474 if (resprod.IsNull())
1477 // A new resbind may have been produced
1478 // DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);
1479 // if (restrans.IsNull()) return resbind;
1480 // FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
1481 // sdr->SetUsedRepresentation(resultat); // to be used by MakeItem
1483 // make location for assembly placement
1484 GeomToStep_MakeAxis2Placement3d mkax (aLoc);
1485 Handle(StepGeom_Axis2Placement3d) AxLoc = mkax.Value();
1488 // create assembly structures (CDSR, NAUO etc.)
1489 STEPConstruct_Assembly mkitem;
1490 mkitem.Init (sdr,SDR0,myContext.GetDefaultAxis(),AxLoc);
1491 mkitem.MakeRelationship ();
1492 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink ( mkitem );
1494 // add roots corresponding to assembly and product structures to binder
1495 //Handle(Transfer_Binder) resprod = resbind; //KA - OCC7141(skl 10.11.2004)
1496 //KA: we need only the current subshape in resprod, since the binder is copied
1497 // in Transfershape which calls Transfersubshape [ OCC7141(skl 10.11.2004) ]
1499 resprod->AddResult ( TransientResult ( SDRTool.SDRValue() ) );
1500 resbind->AddResult ( TransientResult ( SDRTool.SDRValue() ) ); //KA - OCC7141(skl 10.11.2004)
1501 roots->Append ( myContext.GetRootsForPart ( SDRTool ) );
1503 for ( Standard_Integer i=1; i <= roots->Length(); i++ ) {
1504 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
1505 resbind->AddResult ( TransientResult ( roots->Value(i) ) ); //KA - OCC7141(skl 10.11.2004)
1507 myContext.NextIndex();
1509 //FP->Bind (mapper,resprod); //KA - OCC7141(skl 10.11.2004)
1511 // abv 16.10.00: bind CDSR (et al) to located shape in order to be able to track instances
1512 if ( mapper != start ) {
1513 Handle(Transfer_Binder) bnd = FP->Find ( start );
1514 for ( Standard_Integer j=1; j <= roots->Length(); j++ )
1515 if ( bnd.IsNull() ) bnd = TransientResult ( roots->Value(j) );
1516 else bnd->AddResult ( TransientResult ( roots->Value(j) ) );
1517 FP->Bind ( start, bnd );