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.
19 #include <STEPControl_ActorWrite.ixx>
20 #include <STEPControl_StepModelType.hxx>
23 #include <Transfer_SimpleBinderOfTransient.hxx>
25 #include <GeomToStep_MakeAxis2Placement3d.hxx>
26 #include <StepGeom_Axis2Placement3d.hxx>
28 #include <STEPConstruct_Part.hxx>
29 #include <STEPConstruct_Assembly.hxx>
30 #include <STEPConstruct_ContextTool.hxx>
31 #include <STEPConstruct_UnitContext.hxx>
34 #include <TopoDSToStep.hxx>
35 #include <TopoDSToStep_Builder.hxx>
36 #include <TopoDSToStep_FacetedTool.hxx>
37 #include <TopoDSToStep_Tool.hxx>
38 #include <TopoDSToStep_MakeManifoldSolidBrep.hxx>
39 #include <TopoDSToStep_MakeBrepWithVoids.hxx>
40 #include <TopoDSToStep_MakeFacetedBrep.hxx>
41 #include <TopoDSToStep_MakeFacetedBrepAndBrepWithVoids.hxx>
42 #include <TopoDSToStep_MakeGeometricCurveSet.hxx>
43 #include <TopoDSToStep_MakeShellBasedSurfaceModel.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopoDS_Solid.hxx>
48 #include <Geom_Surface.hxx>
49 #include <Geom_Plane.hxx>
50 #include <Geom_Curve.hxx>
51 #include <Geom_Line.hxx>
53 #include <StepShape_ShapeDefinitionRepresentation.hxx>
54 #include <StepShape_FacetedBrepAndBrepWithVoids.hxx>
55 #include <StepShape_FacetedBrep.hxx>
56 #include <StepShape_GeometricCurveSet.hxx>
57 #include <StepShape_ShellBasedSurfaceModel.hxx>
58 #include <StepShape_ManifoldSolidBrep.hxx>
59 #include <StepShape_BrepWithVoids.hxx>
60 #include <StepRepr_HArray1OfRepresentationItem.hxx>
61 #include <StepBasic_HArray1OfProduct.hxx>
62 #include <StepRepr_GlobalUnitAssignedContext.hxx>
63 #include <StepShape_AdvancedBrepShapeRepresentation.hxx>
64 #include <StepShape_FacetedBrepShapeRepresentation.hxx>
65 #include <StepShape_TopologicalRepresentationItem.hxx>
66 #include <StepShape_ManifoldSurfaceShapeRepresentation.hxx>
67 #include <StepShape_GeometricallyBoundedWireframeShapeRepresentation.hxx>
68 #include <StepBasic_ApplicationProtocolDefinition.hxx>
69 #include <StepRepr_PropertyDefinition.hxx>
71 #include <TopExp_Explorer.hxx>
72 #include <TColStd_HSequenceOfTransient.hxx>
73 #include <TCollection_HAsciiString.hxx>
75 #include <Transfer_TransientProcess.hxx>
76 #include <Transfer_Binder.hxx>
77 #include <Transfer_Finder.hxx>
78 #include <Transfer_FinderProcess.hxx>
79 #include <TransferBRep_ShapeMapper.hxx>
80 #include <TransferBRep.hxx>
81 #include <OSD_Timer.hxx>
83 #include <ShapeExtend_Explorer.hxx>
84 #include <ShapeAnalysis_ShapeTolerance.hxx>
85 #include <Interface_MSG.hxx>
86 #include <Interface_Static.hxx>
88 #include <Interface_Macros.hxx>
89 #include <TopTools_HSequenceOfShape.hxx>
91 #include <BRep_Tool.hxx>
92 #include <TopoDS_Iterator.hxx> //:d6
93 #include <UnitsMethods.hxx>
94 #include <STEPConstruct_AP203Context.hxx>
95 #include <BRepTools_Modifier.hxx>
98 #include <XSAlgo_AlgoContainer.hxx>
99 #include <StepRepr_ShapeRepresentationRelationship.hxx>
100 #include <Transfer_SequenceOfBinder.hxx>
102 #include <TopoDSToStep_MakeStepVertex.hxx>
103 #include <StepShape_VertexPoint.hxx>
104 #include <MoniTool_DataMapOfShapeTransient.hxx>
105 #include <StepShape_HArray1OfGeometricSetSelect.hxx>
106 #include <StepShape_GeometricSetSelect.hxx>
107 #include <TopoDS_Compound.hxx>
108 #include <BRep_Builder.hxx>
110 // Non-manifold topology processing (ssv; 10.11.2010)
111 #include <StepShape_NonManifoldSurfaceShapeRepresentation.hxx>
112 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
113 #include <TopTools_ListOfShape.hxx>
114 #include <TopExp.hxx>
115 #include <TopTools_MapOfShape.hxx>
116 #include <TopTools_ListIteratorOfListOfShape.hxx>
118 // ============================================================================
119 // Function: DumpWhatIs
120 // Purpose: Use it in DEB mode to dump your shapes
121 // ============================================================================
124 static void DumpWhatIs(const TopoDS_Shape& S) {
126 TopTools_MapOfShape aMapOfShape;
128 TopTools_ListOfShape aListOfShape;
129 aListOfShape.Append(S);
130 TopTools_ListIteratorOfListOfShape itL(aListOfShape);
131 Standard_Integer nbSolids = 0,
139 for( ; itL.More(); itL.Next() ) {
140 TopoDS_Iterator it( itL.Value() );
141 for ( ; it.More(); it.Next() ) {
142 TopoDS_Shape aSubShape = it.Value();
143 if ( !aMapOfShape.Add(aSubShape) )
145 aListOfShape.Append(aSubShape);
146 if (aSubShape.ShapeType() == TopAbs_SOLID)
148 if (aSubShape.ShapeType() == TopAbs_SHELL) {
149 if ( !aSubShape.Closed() )
153 if (aSubShape.ShapeType() == TopAbs_FACE)
155 if (aSubShape.ShapeType() == TopAbs_WIRE)
157 if (aSubShape.ShapeType() == TopAbs_EDGE)
159 if (aSubShape.ShapeType() == TopAbs_VERTEX)
164 cout << "//What is?// NB SOLIDS: " << nbSolids << endl;
165 cout << "//What is?// NB SHELLS: " << nbShells << endl;
166 cout << "//What is?// OPEN SHELLS: " << nbOpenShells << endl;
167 cout << "//What is?// CLOSED SHELLS: " << nbShells - nbOpenShells << endl;
168 cout << "//What is?// NB FACES: " << nbFaces << endl;
169 cout << "//What is?// NB WIRES: " << nbWires << endl;
170 cout << "//What is?// NB EDGES: " << nbEdges << endl;
171 cout << "//What is?// NB VERTEXES: " << nbVertexes << endl;
175 //=======================================================================
176 // Function : IsManifoldShape
177 // Purpose : Used to define whether the passed shape has manifold
179 //=======================================================================
181 static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
183 Standard_Boolean aResult = Standard_True;
185 // Do not check nested Compounds
186 TopoDS_Compound aDirectShapes;
187 BRep_Builder aBrepBuilder;
188 aBrepBuilder.MakeCompound(aDirectShapes);
190 TopoDS_Iterator anIt(theShape);
191 for ( ; anIt.More(); anIt.Next() ) {
192 TopoDS_Shape aDirectChild = anIt.Value();
193 if (aDirectChild.ShapeType() != TopAbs_COMPOUND)
194 aBrepBuilder.Add(aDirectShapes, aDirectChild);
198 DumpWhatIs(aDirectShapes);
201 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
202 TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
204 Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
206 cout << "Checking whether the topology passed is manifold..." << endl;
210 for (Standard_Integer i = 1; i <= aNbEdges; i++) {
211 TopoDS_Edge aCurrentEdge = TopoDS::Edge( aMapEdgeFaces.FindKey(i) );
212 if ( !BRep_Tool::Degenerated(aCurrentEdge) ) {
213 Standard_Integer aNbAncestors = aMapEdgeFaces.FindFromIndex(i).Extent();
214 if (aNbAncestors > 2) {
215 aResult = Standard_False;
222 cout << "Check result: "
223 << (aResult ? "TRUE" : "FALSE") << endl;
229 /* this is a start of a comment! */
231 void DumpBinder (const Handle(Transfer_Binder) &binder)
233 Handle(Transfer_Binder) bbb = binder;
234 while ( ! bbb.IsNull() ) {
235 Handle(Transfer_SimpleBinderOfTransient) bx =
236 Handle(Transfer_SimpleBinderOfTransient)::DownCast ( bbb );
238 if ( ! bx.IsNull() ) {
239 cout << "--> " << bx->ResultTypeName() << " " << *(void**)&bx->Result() << endl;
241 else cout << "--> ???" << endl;
242 bbb = bbb->NextResult();
247 /* this is a end of a comment */
249 //=======================================================================
250 //function : STEPControl_ActorWrite
252 //=======================================================================
254 STEPControl_ActorWrite::STEPControl_ActorWrite ()
255 : mygroup (0) , mytoler (-1.)
257 SetMode(STEPControl_ShellBasedSurfaceModel);
260 //=======================================================================
261 //method: getNMSSRForGroup
262 //purpose: allows to get NMSSR (NON_MANIFOLD_SURFACE_SHAPE_REPRESENTATION)
263 // STEP's entity for the group of shells (!) passed
264 //=======================================================================
266 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::getNMSSRForGroup(const Handle(TopTools_HSequenceOfShape)& shapeGroup,
267 const Handle(Transfer_FinderProcess)& FP,
268 Standard_Boolean& isNMSSRCreated) const
270 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) aResult;
272 if ( !shapeGroup.IsNull() ) {
273 for (Standard_Integer i = 1; i <= shapeGroup->Length(); i++) {
274 TopoDS_Shape aCurrentShape = shapeGroup->Value(i);
275 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper(FP, aCurrentShape);
276 if ( FP->FindTypedTransient(mapper, STANDARD_TYPE(StepShape_NonManifoldSurfaceShapeRepresentation), aResult) )
281 if ( aResult.IsNull() ) {
283 cout << "\nNew NMSSR created" << endl;
285 aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
286 isNMSSRCreated = Standard_True;
289 cout << "\nExisting NMSSR is used" << endl;
291 isNMSSRCreated = Standard_False;
298 //=======================================================================
301 //=======================================================================
303 void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
306 case STEPControl_AsIs : ModeTrans() = 0; break;
307 case STEPControl_ManifoldSolidBrep : ModeTrans() = 3; break;
308 case STEPControl_BrepWithVoids : ModeTrans() = 5; break;
309 case STEPControl_FacetedBrep : ModeTrans() = 1; break;
310 case STEPControl_FacetedBrepAndBrepWithVoids : ModeTrans() = 6; break;
311 case STEPControl_ShellBasedSurfaceModel : ModeTrans() = 2;
312 case STEPControl_GeometricCurveSet : ModeTrans() = 4;
313 case STEPControl_Hybrid : ModeTrans() = 0; break; // PAS IMPLEMENTE !!
318 //=======================================================================
321 //=======================================================================
323 STEPControl_StepModelType STEPControl_ActorWrite::Mode () const
325 switch (themodetrans) {
326 case 0 : return STEPControl_AsIs;
327 case 1 : return STEPControl_FacetedBrep;
328 case 2 : return STEPControl_ShellBasedSurfaceModel;
329 case 3 : return STEPControl_ManifoldSolidBrep;
330 case 4 : return STEPControl_GeometricCurveSet;
331 case 5 : return STEPControl_BrepWithVoids;
332 case 6 : return STEPControl_FacetedBrepAndBrepWithVoids;
335 return STEPControl_AsIs;
338 //=======================================================================
339 //function : SetGroupMode
341 //=======================================================================
343 void STEPControl_ActorWrite::SetGroupMode (const Standard_Integer mode)
345 if (mode >= 0) mygroup = mode;
348 //=======================================================================
349 //function : GroupMode
351 //=======================================================================
353 Standard_Integer STEPControl_ActorWrite::GroupMode () const
358 //=======================================================================
359 //function : SetTolerance
361 //=======================================================================
363 void STEPControl_ActorWrite::SetTolerance (const Standard_Real Tol)
368 //=======================================================================
369 //function : Recognize
370 // ATTENTION, Recognize doit s aligner sur ce que Transfer sait faire
372 //=======================================================================
374 Standard_Boolean STEPControl_ActorWrite::Recognize (const Handle(Transfer_Finder)& start)
376 STEPControl_StepModelType mymode = Mode();
377 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
378 if (mapper.IsNull()) return Standard_False;
379 if (mymode == STEPControl_AsIs) return Standard_True;
381 Standard_Boolean yasolid = Standard_False, yashell = Standard_False,
382 yaface = Standard_False;
384 TopoDS_Shape theShape, aShape;
385 // theShape = TopoDSToStep::DirectFaces(mapper->Value());
386 theShape = mapper->Value(); // pour une reconnaissance c est bien assez
388 if (theShape.ShapeType() == TopAbs_COMPOUND) {
390 TopExp_Explorer SolidExp, ShellExp, FaceExp;
392 for (SolidExp.Init(theShape, TopAbs_SOLID);
393 SolidExp.More();SolidExp.Next()) yasolid = Standard_True;
394 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
395 ShellExp.More();ShellExp.Next()) yashell = Standard_True;
396 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
397 FaceExp.More();FaceExp.Next()) yaface = Standard_True;
399 else if (theShape.ShapeType() == TopAbs_SOLID) yasolid = Standard_True;
400 else if (theShape.ShapeType() == TopAbs_SHELL) yashell = Standard_True;
401 else if (theShape.ShapeType() == TopAbs_FACE) yaface = Standard_True;
402 else if (mymode != STEPControl_GeometricCurveSet) return Standard_False;
405 // Faceted : il est OBLIGATOIRE d avoir des surfaces support Plane et des
406 // courbes 3D Line (pcurves ignorees)
408 if (mymode == STEPControl_FacetedBrep || mymode == STEPControl_FacetedBrepAndBrepWithVoids) {
409 for (TopExp_Explorer ffac(theShape,TopAbs_FACE); ffac.More(); ffac.Next()) {
410 const TopoDS_Face& F = TopoDS::Face (ffac.Current());
411 TopLoc_Location locbid;
412 Handle(Geom_Surface) surf = BRep_Tool::Surface (F,locbid);
413 if (surf.IsNull() || !surf->IsKind(STANDARD_TYPE(Geom_Plane)) ) return Standard_False;
415 for (TopExp_Explorer fedg(theShape,TopAbs_EDGE); fedg.More(); fedg.Next()) {
416 const TopoDS_Edge& E = TopoDS::Edge (fedg.Current());
417 TopLoc_Location locbid; Standard_Real first,last;
418 Handle(Geom_Curve) curv = BRep_Tool::Curve (E,locbid,first,last);
419 if (curv.IsNull() || !curv->IsKind(STANDARD_TYPE(Geom_Line)) ) return Standard_False;
424 case STEPControl_ManifoldSolidBrep: return (yasolid || yashell);
425 case STEPControl_BrepWithVoids:
426 case STEPControl_FacetedBrep:
427 case STEPControl_FacetedBrepAndBrepWithVoids: return yasolid;
428 case STEPControl_ShellBasedSurfaceModel:
429 return (yasolid || yashell || yaface);
430 case STEPControl_GeometricCurveSet: return Standard_True; // tout OK
433 return Standard_False;
437 // ######## MAKE PRODUCT DATA + CONTEXT ########
439 //=======================================================================
440 //function : Transfer
442 //=======================================================================
444 Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_Finder)& start,
445 const Handle(Transfer_FinderProcess)& FP)
447 XSAlgo::AlgoContainer()->PrepareForTransfer();
449 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
451 if (mapper.IsNull()) return NullResult();
452 TopoDS_Shape shape = mapper->Value();
455 Handle(StepData_StepModel) model = Handle(StepData_StepModel)::DownCast ( FP->Model() );
456 if ( ! model.IsNull() ) myContext.SetModel ( model ); //: abv 04.11.00: take APD from model
457 myContext.AddAPD ( Standard_False ); // update APD
458 myContext.SetLevel ( 1 ); // set assembly level to 1 (to ensure)
460 //:S4136: init UnitsMethods to reset angle unit factors (see TopoDSToStep)
461 Standard_Real lFactor = UnitsMethods::GetLengthFactorValue ( Interface_Static::IVal ( "write.step.unit" ) );
462 lFactor /= UnitsMethods::GetCasCadeLengthUnit();
463 Standard_Integer anglemode = Interface_Static::IVal("step.angleunit.mode");
464 UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
467 STEPConstruct_Part SDRTool;
468 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
469 Handle(StepShape_ShapeDefinitionRepresentation) sdr = SDRTool.SDRValue();
472 Handle(Transfer_Binder) resbind = TransferShape (mapper,sdr,FP);
474 // Handle(StepShape_ShapeRepresentation) resultat;
475 // FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
476 // sdr->SetUsedRepresentation (resultat);
478 // create binder with all root entities produced from shape
479 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForPart ( SDRTool );
480 Handle(Transfer_Binder) resprod = TransientResult ( myContext.GetAPD() );
481 for ( Standard_Integer i=1; i <= roots->Length(); i++ )
482 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
483 resprod->AddResult(resbind);
486 //FP->Bind (mapper,resprod);
487 myContext.NextIndex();
491 //==========================================
493 static Standard_Real UsedTolerance (const Standard_Real mytoler,
494 const TopoDS_Shape& theShape)
497 // COMPUTING 3D TOLERANCE
498 // Either from Session, or Computed (Least,Average, or Greatest)
499 // Then given to TopoDSToStep_Tool
501 Standard_Real Tol = mytoler;
502 Standard_Integer tolmod = Interface_Static::IVal("write.precision.mode");
503 if (Tol <= 0 && tolmod == 2) Tol =
504 Interface_Static::RVal("write.precision.val");
506 ShapeAnalysis_ShapeTolerance stu;
507 Tol = stu.Tolerance (theShape,tolmod);
508 // Par defaut, on prend une tolerance moyenne, on elimine les aberrations
509 Tol = Interface_MSG::Intervalled (Tol * 1.5); // arrondi a 1 2 5 ...
511 if (Tol == 0) Tol = 1.e-07; // minimum ...
516 //=======================================================================
517 //function : IsAssembly
519 //=======================================================================
520 // if GroupMode is >1 downgrades all compounds having single subshape to that
523 Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
525 if ( ! GroupMode() || S.ShapeType() != TopAbs_COMPOUND ) return Standard_False;
526 // PTV 16.09.2002 OCC725 for storing compound of vertices
527 if (S.ShapeType() == TopAbs_COMPOUND ) {
528 Standard_Boolean IsOnlyVertices = Standard_True;
529 TopoDS_Iterator anItr( S );
530 for ( ; anItr.More(); anItr.Next() ) {
531 if ( anItr.Value().ShapeType() != TopAbs_VERTEX ) {
532 IsOnlyVertices = Standard_False;
536 if ( IsOnlyVertices )
537 return Standard_False;
539 if ( GroupMode() ==1 ) return Standard_True;
540 TopoDS_Iterator it ( S );
541 if ( ! it.More() ) return Standard_False;
542 TopoDS_Shape shape = it.Value();
544 if ( it.More() ) return Standard_True;
546 return IsAssembly ( S );
549 //=======================================================================
550 //function : TransferShape
552 //=======================================================================
555 static void UpdateMap (const TopoDS_Shape &shape,
556 BRepTools_Modifier &M1,
557 BRepTools_Modifier &M2,
558 const Handle(Transfer_FinderProcess) &FinderProcess)
560 TopoDS_Shape S = M1.ModifiedShape ( shape );
561 S = M2.ModifiedShape ( S );
562 if ( S == shape ) return;
564 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper ( FinderProcess, S );
565 Handle(Transfer_Binder) binder = FinderProcess->Find ( mapper );
566 if ( ! binder.IsNull() ) {
567 mapper = TransferBRep::ShapeMapper ( FinderProcess, shape );
568 FinderProcess->Bind ( mapper, binder );
571 for ( TopoDS_Iterator it(shape); it.More(); it.Next() )
572 UpdateMap ( it.Value(), M1, M2, FinderProcess );
576 // PTV 16.09.2002 added for transfering vertices.
577 static Standard_Boolean transferVertex (const Handle(Transfer_FinderProcess)& FP,
578 Handle(StepShape_HArray1OfGeometricSetSelect)& aGSS,
579 const TopoDS_Shape& aShVrtx,
580 const Standard_Integer theNum)
582 Standard_Boolean IsDone = Standard_False;
583 MoniTool_DataMapOfShapeTransient aMap;
584 TopoDSToStep_Tool aTool(aMap, Standard_True);
585 TopoDSToStep_MakeStepVertex aMkVrtx ( TopoDS::Vertex(aShVrtx), aTool, FP );
587 if (!aMkVrtx.IsDone())
590 Handle(StepShape_VertexPoint) aVP =
591 Handle(StepShape_VertexPoint)::DownCast(aTool.Find(aShVrtx));
595 StepShape_GeometricSetSelect select;
596 select.SetValue(aVP->VertexGeometry());
597 // add current result
598 aGSS->SetValue( theNum, select );
599 IsDone = Standard_True;
604 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Transfer_Finder)& start,
605 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
606 const Handle(Transfer_FinderProcess)& FP,
607 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
608 const Standard_Boolean isManifold)
610 STEPControl_StepModelType mymode = Mode();
611 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
612 Handle(Transfer_Binder) binder;
614 // Indicates whether to use an exising NMSSR to write items to (ss; 13.11.2010)
615 Standard_Boolean useExistingNMSSR = Standard_False;
617 if (mapper.IsNull()) return binder;
618 TopoDS_Shape theShape = mapper->Value();
620 if (theShape.IsNull()) return binder;
622 // INDIVIDUAL SHAPE ALREADY TRANSFERRED : RETURN IT !
623 binder = FP->Find(start);
624 if (!binder.IsNull()) { if (!binder->HasResult()) binder.Nullify(); }
625 if (!binder.IsNull()) {
626 //:abv 20.05.02: writing box & face from it (shared) in one compound
627 // as assembly - while face already translated, it should be
628 // re-translated to break sharing
630 cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << endl;
635 // MODE ASSEMBLY : if Compound, (sub-)assembly
636 if ( IsAssembly(theShape) )
637 return TransferCompound(start, SDR0, FP);
639 // [BEGIN] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
640 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
641 Handle(Transfer_Binder) aNMBinder;
642 if (isNMMode && !GroupMode() && theShape.ShapeType() == TopAbs_COMPOUND) {
643 TopoDS_Compound aNMCompound;
644 TopoDS_Compound aManifoldCompound;
645 BRep_Builder brepBuilder;
647 // Create empty Compounds
648 brepBuilder.MakeCompound(aManifoldCompound);
649 brepBuilder.MakeCompound(aNMCompound);
651 // Indicates whether there is only non-manifold topology detected
652 // (there is no manifold topology found in the Compound passed)
653 Standard_Boolean isOnlyNonManifold = Standard_False;
655 // Find a Compound containing non-manifold topology.
656 // NOTE: only one such Compound must exist in the entire Compound passed
657 if ( !IsManifoldShape(theShape) ) {
658 aNMCompound = TopoDS::Compound(theShape);
659 isOnlyNonManifold = Standard_True;
662 TopTools_ListOfShape aListOfShapes;
663 TopTools_ListOfShape aListOfManifoldShapes;
664 aListOfShapes.Append(theShape);
666 TopTools_ListIteratorOfListOfShape itL(aListOfShapes);
667 for ( ; itL.More(); itL.Next() ) {
668 TopoDS_Shape aParentShape = itL.Value();
669 TopoDS_Iterator it(aParentShape);
670 for ( ; it.More(); it.Next() ) {
671 TopoDS_Shape aSubShape = it.Value();
672 if (aSubShape.ShapeType() == TopAbs_COMPOUND && !IsManifoldShape(aSubShape) )
673 aNMCompound = TopoDS::Compound(aSubShape);
674 else if (aSubShape.ShapeType() == TopAbs_COMPOUND)
675 aListOfShapes.Append(aSubShape);
677 aListOfManifoldShapes.Append(aSubShape);
681 // Group manifold topology together.
682 // NOTE: there is no sense that initial Compound structure was lost as
683 // group mode is set to 0 (no Assemblies are mapped)
684 for ( itL.Initialize(aListOfManifoldShapes); itL.More(); itL.Next() ) {
685 TopoDS_Shape aCurrentManiShape = itL.Value();
686 brepBuilder.Add(aManifoldCompound, aCurrentManiShape);
691 // Process only manifold topology in the current TransferShape invocation.
692 // Invoke TransferShape for non-manifold topology separately (see below)
693 theShape = aManifoldCompound;
695 // List of items to transfer
696 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
697 // Non-manifold group to pass into TransferShape with each shape from RepItemSeq
698 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
700 // Transfer Solids to closed Shells. Prepare RepItemSeq & NonManifoldGroup
701 for ( TopoDS_Iterator iter(aNMCompound); iter.More(); iter.Next() ) {
702 TopoDS_Shape aSubShape = iter.Value();
703 if (aSubShape.ShapeType() == TopAbs_SOLID) {
704 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
705 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
706 aSubShell.Closed(Standard_True);
707 RepItemSeq->Append(aSubShell);
708 NonManifoldGroup->Append(aSubShell);
711 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
712 RepItemSeq->Append(aSubShape);
713 NonManifoldGroup->Append(aSubShape);
716 RepItemSeq->Append( iter.Value() );
719 Standard_Integer aNMItemsNb = RepItemSeq->Length();
721 // In case of pure manifold topology do nothing; theShape is processed as usual (see below)
722 if (aNMItemsNb > 0) {
724 // Prepare SDR for non-manifold group. This SDR will be linked to NMSSR by means
725 // of TransferShape invocation. SDR is not created if there is no any manifold
726 // topology in the passed Compound. If topology is pure non-manifold, SDR0 (passed)
728 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
729 if (isOnlyNonManifold)
732 STEPConstruct_Part SDRTool;
733 SDRTool.MakeSDR( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
734 sdr = SDRTool.SDRValue();
737 aNMBinder = TransientResult(sdr);
739 // Complete SDR with shape representations.
740 // NOTE: aNMBinder is connected now with this SDR. It will be added to the resulting
741 // binder in the end of this invocation of TransferShape
742 for (Standard_Integer i = 1; i <= aNMItemsNb; i++) {
743 Handle(TransferBRep_ShapeMapper) mapper = TransferBRep::ShapeMapper( FP, RepItemSeq->Value(i) );
744 TransferShape(mapper, sdr, FP, NonManifoldGroup, Standard_False);
747 // Nothing else needed for pure non-manifold topology, return
748 if (isOnlyNonManifold)
754 // [END] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
756 // create a list of items to translate
757 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
759 // PTV 16.09.2002 OCC725 separate shape from solo vertices.
760 Standard_Boolean isOnlyVertices = Standard_False;
761 if (theShape.ShapeType() == TopAbs_COMPOUND) {
762 Standard_Integer countVrtx = 0;
763 Standard_Integer countSh = 0;
764 TopoDS_Compound aNewShape, aCompOfVrtx;
766 aB.MakeCompound(aNewShape);
767 aB.MakeCompound(aCompOfVrtx);
768 TopoDS_Iterator anCompIt(theShape);
769 for (; anCompIt.More(); anCompIt.Next()) {
770 TopoDS_Shape aCurSh = anCompIt.Value();
771 if (aCurSh.ShapeType() != TopAbs_VERTEX) {
772 aB.Add(aNewShape, aCurSh);
776 aB.Add(aCompOfVrtx, aCurSh);
780 // replace the shapes
782 theShape = aNewShape;
784 RepItemSeq->Append(aCompOfVrtx);
786 isOnlyVertices = Standard_True;
789 if (theShape.ShapeType() == TopAbs_COMPOUND) {
790 TopExp_Explorer SolidExp, ShellExp, FaceExp;
791 if (mymode != STEPControl_GeometricCurveSet) {
792 for (SolidExp.Init(theShape, TopAbs_SOLID);
793 SolidExp.More();SolidExp.Next()) {
794 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
796 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
797 ShellExp.More();ShellExp.Next()) {
798 RepItemSeq->Append(TopoDS::Shell(ShellExp.Current()));
801 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
802 FaceExp.More();FaceExp.Next()) {
803 RepItemSeq->Append(TopoDS::Face(FaceExp.Current()));
808 RepItemSeq->Append(theShape); //:j1
810 if(mymode == STEPControl_AsIs) {
811 TopExp_Explorer WireExp, EdgeExp;
812 for (WireExp.Init(theShape, TopAbs_WIRE, TopAbs_FACE);
813 WireExp.More();WireExp.Next())
814 RepItemSeq->Append(TopoDS::Wire(WireExp.Current()));
815 for (EdgeExp.Init(theShape, TopAbs_EDGE, TopAbs_WIRE);
816 EdgeExp.More();EdgeExp.Next())
817 RepItemSeq->Append(TopoDS::Edge(EdgeExp.Current()));
821 else if (theShape.ShapeType() == TopAbs_SOLID) {
822 RepItemSeq->Append(TopoDS::Solid(theShape));
824 else if (theShape.ShapeType() == TopAbs_SHELL) {
825 RepItemSeq->Append(TopoDS::Shell(theShape));
827 else if (theShape.ShapeType() == TopAbs_FACE) {
828 RepItemSeq->Append(TopoDS::Face(theShape));
830 else if (theShape.ShapeType() == TopAbs_COMPSOLID) {
831 FP->AddWarning(start,"NonManifold COMPSOLID was translated like a set of SOLIDs");
832 if ( GroupMode() > 0)
833 return TransferCompound(start, SDR0, FP);
835 TopExp_Explorer SolidExp;
836 for (SolidExp.Init(theShape, TopAbs_SOLID);
837 SolidExp.More();SolidExp.Next()) {
838 RepItemSeq->Append(TopoDS::Solid(SolidExp.Current()));
843 else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
844 FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
847 else RepItemSeq->Append (theShape);
849 // COMPUTING 3D TOLERANCE
850 // Either from Session, or Computed (Least,Average, or Greatest)
851 // Then given to TopoDSToStep_Tool
852 Standard_Real Tol = UsedTolerance (mytoler,theShape);
854 // Create a STEP-Entity for each TopoDS_Shape
855 // according to the current StepModelMode
857 Standard_Integer nbs = RepItemSeq->Length();
858 Handle(TColStd_HSequenceOfTransient) ItemSeq =
859 new TColStd_HSequenceOfTransient();
861 //ptv 10.11.00: allow to write empty Compound: if (GroupMode() >0)
862 ItemSeq->Append (myContext.GetDefaultAxis());
863 STEPControl_StepModelType trmode = mymode;
864 for (Standard_Integer i = 1; i <= nbs; i++) {
865 TopoDS_Shape xShape = RepItemSeq->Value(i);
867 if(mymode == STEPControl_AsIs) {
868 switch(xShape.ShapeType()) {
869 case TopAbs_SOLID : trmode = STEPControl_ManifoldSolidBrep;break;
870 case TopAbs_SHELL : trmode = STEPControl_ShellBasedSurfaceModel; break;
871 case TopAbs_FACE : trmode = STEPControl_ShellBasedSurfaceModel;break;
872 default : trmode =STEPControl_GeometricCurveSet; break;
875 //:abv 24Jan99 CAX-IF TRJ3: expanded Shape Processing
876 // TopoDS_Shape aShape = xShape;
877 // eliminate conical surfaces with negative semiangles
878 // Handle(TopoDSToStep_ConicalSurfModif) CSM = new TopoDSToStep_ConicalSurfModif();
879 // BRepTools_Modifier CSMT(aShape,CSM);
880 // if ( CSMT.IsDone() ) aShape = CSMT.ModifiedShape ( aShape );
881 // // eliminate indirect elementary surfaces
882 // Handle(TopoDSToStep_DirectModification) DM = new TopoDSToStep_DirectModification();
883 // BRepTools_Modifier DMT(aShape,DM);
884 // if ( DMT.IsDone() ) aShape = DMT.ModifiedShape ( aShape );
885 //// aShape = TopoDSToStep::DirectFaces(xShape);
886 Handle(Standard_Transient) info;
887 Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
889 // Fix only manifold shapes, do nothing with non-manifold topology as it is processed separately (ssv; 13.11.2010)
892 aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol,
893 "write.step.resource.name",
894 "write.step.sequence", info,
899 // create a STEP entity corresponding to shape
900 Handle(StepGeom_GeometricRepresentationItem) item;
903 case STEPControl_ManifoldSolidBrep:
905 if (aShape.ShapeType() == TopAbs_SOLID) {
906 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
908 //:d6 abv 13 Mar 98: if solid has more than 1 shell,
909 // try to treat it as solid with voids
910 Standard_Integer nbShells = 0;
911 for ( TopoDS_Iterator It ( aSolid ); It.More(); It.Next() )
912 if (It.Value().ShapeType() == TopAbs_SHELL) nbShells++;
914 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
915 MkBRepWithVoids.Tolerance() = Tol;
916 if (MkBRepWithVoids.IsDone()) {
917 item = MkBRepWithVoids.Value();
919 else nbShells = 1; //smth went wrong; let it will be just Manifold
921 if ( nbShells ==1 ) {
923 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aSolid,FP);
924 MkManifoldSolidBrep.Tolerance() = Tol;
925 if (MkManifoldSolidBrep.IsDone()) {
926 item = MkManifoldSolidBrep.Value();
930 else if (aShape.ShapeType() == TopAbs_SHELL) {
931 TopoDS_Shell aShell = TopoDS::Shell(aShape);
932 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aShell,FP);
933 MkManifoldSolidBrep.Tolerance() = Tol;
934 if (MkManifoldSolidBrep.IsDone()) {
935 item = MkManifoldSolidBrep.Value();
940 case STEPControl_BrepWithVoids:
942 if (aShape.ShapeType() == TopAbs_SOLID) {
943 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
944 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
945 MkBRepWithVoids.Tolerance() = Tol;
946 if (MkBRepWithVoids.IsDone()) {
947 item = MkBRepWithVoids.Value();
952 case STEPControl_FacetedBrep:
954 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
955 if (facErr != TopoDSToStep_FacetedDone) {
956 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
957 if (facErr == TopoDSToStep_SurfaceNotPlane) {
958 FP->AddFail(start,"-- The TopoDS_Face is not plane");
960 else if (facErr == TopoDSToStep_PCurveNotLinear) {
961 FP->AddFail(start,"-- The Face contains non linear PCurves");
965 if (aShape.ShapeType() == TopAbs_SOLID) {
966 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
967 TopoDSToStep_MakeFacetedBrep MkFacetedBrep(aSolid,FP);
968 MkFacetedBrep.Tolerance() = Tol;
969 if (MkFacetedBrep.IsDone()) {
970 item = MkFacetedBrep.Value();
975 case STEPControl_FacetedBrepAndBrepWithVoids:
977 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
978 if (facErr != TopoDSToStep_FacetedDone) {
979 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
980 if (facErr == TopoDSToStep_SurfaceNotPlane) {
981 FP->AddFail(start,"-- The TopoDS_Face is not plane");
983 else if (facErr == TopoDSToStep_PCurveNotLinear) {
984 FP->AddFail(start,"-- The Face contains non linear PCurves");
988 if (aShape.ShapeType() == TopAbs_SOLID) {
989 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
990 TopoDSToStep_MakeFacetedBrepAndBrepWithVoids
991 MkFacetedBrepAndBrepWithVoids(aSolid,FP);
992 MkFacetedBrepAndBrepWithVoids.Tolerance() = Tol;
993 if (MkFacetedBrepAndBrepWithVoids.IsDone()) {
994 item = MkFacetedBrepAndBrepWithVoids.Value();
999 case STEPControl_ShellBasedSurfaceModel:
1001 if (aShape.ShapeType() == TopAbs_SOLID) {
1002 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
1003 TopoDSToStep_MakeShellBasedSurfaceModel
1004 MkShellBasedSurfaceModel(aSolid, FP);
1005 MkShellBasedSurfaceModel.Tolerance() = Tol;
1006 if (MkShellBasedSurfaceModel.IsDone()) {
1007 item = MkShellBasedSurfaceModel.Value();
1010 else if (aShape.ShapeType() == TopAbs_SHELL) {
1011 TopoDS_Shell aShell = TopoDS::Shell(aShape);
1012 // Non-manifold topology is stored via NMSSR containing series of SBSM (ssv; 13.11.2010)
1013 TopoDSToStep_MakeShellBasedSurfaceModel MkShellBasedSurfaceModel(aShell, FP);
1014 MkShellBasedSurfaceModel.Tolerance() = Tol;
1015 if (MkShellBasedSurfaceModel.IsDone()) {
1016 item = MkShellBasedSurfaceModel.Value();
1019 else if (aShape.ShapeType() == TopAbs_FACE) {
1020 TopoDS_Face aFace = TopoDS::Face(aShape);
1021 TopoDSToStep_MakeShellBasedSurfaceModel
1022 MkShellBasedSurfaceModel(aFace, FP);
1023 MkShellBasedSurfaceModel.Tolerance() = Tol;
1024 if (MkShellBasedSurfaceModel.IsDone()) {
1025 item = MkShellBasedSurfaceModel.Value();
1030 case STEPControl_GeometricCurveSet:
1032 TopoDSToStep_MakeGeometricCurveSet MkGeometricCurveSet(aShape,FP);
1033 MkGeometricCurveSet.Tolerance() = Tol;
1034 if (MkGeometricCurveSet.IsDone()) {
1035 item = MkGeometricCurveSet.Value();
1037 // PTV 22.08.2002 OCC609 ------------------------- begin --------------------
1038 // modified by PTV 16.09.2002 OCC725
1039 else if (aShape.ShapeType() == TopAbs_COMPOUND ||
1040 aShape.ShapeType() == TopAbs_VERTEX) {
1041 // it is compund with solo vertices.
1042 Standard_Integer aNbVrtx = 0;
1043 Standard_Integer curNb = 0;
1044 TopExp_Explorer anExp (aShape, TopAbs_VERTEX);
1045 for ( ; anExp.More(); anExp.Next() ) {
1046 if ( anExp.Current().ShapeType() != TopAbs_VERTEX )
1051 // create new geometric curve set for all vertices
1052 Handle(StepShape_HArray1OfGeometricSetSelect) aGSS =
1053 new StepShape_HArray1OfGeometricSetSelect(1,aNbVrtx);
1054 Handle(TCollection_HAsciiString) empty = new TCollection_HAsciiString("");
1055 Handle(StepShape_GeometricCurveSet) aGCSet =
1056 new StepShape_GeometricCurveSet;
1057 aGCSet->SetName(empty);
1058 // iterates on compound with vertices and trances each vertex
1059 for ( anExp.ReInit() ; anExp.More(); anExp.Next() ) {
1060 TopoDS_Shape aVertex = anExp.Current();
1061 if ( aVertex.ShapeType() != TopAbs_VERTEX )
1064 transferVertex (FP, aGSS, aVertex, curNb);
1065 } // end of iteration on compound with vertices.
1066 aGCSet->SetElements(aGSS);
1068 } // end of check that number of vertices is not null
1070 // PTV 22.08.2002 OCC609------------------------- end --------------------
1075 if ( item.IsNull() ) continue;
1077 // add resulting item to the FP
1078 ItemSeq->Append(item);
1079 Handle(TransferBRep_ShapeMapper) submapper;
1080 if ( xShape.IsSame ( mapper->Value() ) )
1081 submapper = Handle(TransferBRep_ShapeMapper)::DownCast ( start );
1082 if ( submapper.IsNull() ) submapper = TransferBRep::ShapeMapper (FP,xShape);
1083 Handle(Transfer_Binder) subbind = FP->Find ( submapper );
1084 if ( subbind.IsNull() ) {
1085 subbind = TransientResult ( item );
1086 FP->Bind ( submapper, subbind );
1088 else subbind->AddResult ( TransientResult ( item ) );
1090 //:abv 24Jan99 CAX-IF TRJ3: Update FinderProcess map to take into account shape processing
1091 // UpdateMap ( xShape, CSMT, DMT, FP );
1092 XSAlgo::AlgoContainer()->MergeTransferInfo(FP, info);
1095 // - Make Shape Representation
1096 Standard_Integer nCc1 = ItemSeq->Length();
1098 FP->AddFail(start,"The Shape has not the appropriate type");
1101 Handle(StepShape_ShapeRepresentation) shapeRep;
1102 if ( theShape.ShapeType() == TopAbs_SHAPE ) { // for external references
1103 shapeRep = new StepShape_ShapeRepresentation;
1107 case STEPControl_ManifoldSolidBrep:
1108 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1110 case STEPControl_FacetedBrep:
1111 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1113 // NOTE: STEPControl_AsIs mode is normally used to transfer non-manifold topology.
1114 // However, as ShellBasedSurfaceModel is used in non-manifold processing
1115 // internally, STEPControl_ShellBasedSurfaceModel is also adjusted to
1116 // be able to work with non-manifold cases
1117 case STEPControl_ShellBasedSurfaceModel:
1119 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1121 Standard_Boolean isNewNMSSRCreated;
1122 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1123 useExistingNMSSR = !isNewNMSSRCreated;
1126 case STEPControl_GeometricCurveSet:
1127 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1129 case STEPControl_AsIs :
1132 if(trmode == STEPControl_ManifoldSolidBrep)
1133 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1134 else if(trmode == STEPControl_ShellBasedSurfaceModel)
1135 // Process non-manifold topology separately (ssv; 13.11.2010)
1137 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1139 Standard_Boolean isNewNMSSRCreated;
1140 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1141 useExistingNMSSR = !isNewNMSSRCreated;
1143 else if(trmode == STEPControl_GeometricCurveSet)
1144 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1145 else if(trmode ==STEPControl_FacetedBrep)
1146 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1148 else shapeRep = new StepShape_ShapeRepresentation;
1154 if(shapeRep.IsNull()) {
1155 Handle(Transfer_Binder) resb;
1159 Handle(StepRepr_HArray1OfRepresentationItem) items =
1160 new StepRepr_HArray1OfRepresentationItem(1,nCc1);
1162 for (Standard_Integer rep = 1; rep <= nCc1; rep++) {
1163 Handle(StepRepr_RepresentationItem) repit =
1164 GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep));
1165 items->SetValue(rep,repit);
1167 Standard_Integer ap = Interface_Static::IVal("write.step.schema");
1168 Transfer_SequenceOfBinder aSeqBindRelation;
1169 if(ap == 3 && nbs > 1) {
1170 Standard_Integer j = 1;
1171 if(items->Value(j)->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d))) {
1172 Handle(StepRepr_HArray1OfRepresentationItem) axis =
1173 new StepRepr_HArray1OfRepresentationItem(1,1);
1174 axis->SetValue(1,items->Value(j++));
1175 shapeRep->SetItems(axis);
1177 for (; j <= items->Length(); j++) {
1179 Handle(StepShape_ShapeRepresentation) ShapeRepr1;
1180 if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep)))
1181 ShapeRepr1 = new StepShape_AdvancedBrepShapeRepresentation;
1182 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel)))
1183 ShapeRepr1 = new StepShape_ManifoldSurfaceShapeRepresentation;
1184 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_GeometricCurveSet)))
1185 ShapeRepr1 = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1186 else if (items->Value(j)->IsKind(STANDARD_TYPE(StepShape_FacetedBrep)))
1187 ShapeRepr1 = new StepShape_FacetedBrepShapeRepresentation;
1188 else ShapeRepr1 = new StepShape_ShapeRepresentation;
1190 Handle(StepRepr_HArray1OfRepresentationItem) repr1 = new StepRepr_HArray1OfRepresentationItem(1,2);
1191 repr1->SetValue(1,myContext.GetDefaultAxis());
1192 repr1->SetValue(2,items->Value(j));
1193 ShapeRepr1->SetItems(repr1);
1194 STEPConstruct_UnitContext mk1;
1196 ShapeRepr1->SetContextOfItems(mk1.Value()); // la tolerance, voir au debut
1197 ShapeRepr1->SetName (new TCollection_HAsciiString(""));
1199 Handle(StepRepr_ShapeRepresentationRelationship) aShapeRel = new StepRepr_ShapeRepresentationRelationship;
1200 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
1201 Handle(TCollection_HAsciiString) aDescr = new TCollection_HAsciiString("");
1202 aShapeRel->SetName(aName);
1203 aShapeRel->SetDescription(aDescr);
1204 aShapeRel->SetRep2(shapeRep);
1205 aShapeRel->SetRep1(ShapeRepr1);
1207 aSeqBindRelation.Append(TransientResult (aShapeRel));
1211 if (!useExistingNMSSR)
1212 shapeRep->SetItems(items);
1214 // Add new representation item to the NMSSR's existing collection (ssv; 13.11.2010)
1215 Handle(StepRepr_HArray1OfRepresentationItem) oldItems = shapeRep->Items();
1216 Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1217 new StepRepr_HArray1OfRepresentationItem(1, oldItems->Length() + 1);
1218 Standard_Integer el = 1;
1219 for (Standard_Integer i = 1; i <= oldItems->Length(); i++)
1220 newItems->SetValue( el++, oldItems->Value(i) );
1221 newItems->SetValue( el, items->Value( items->Length() ) );
1222 shapeRep->SetItems(newItems);
1226 // init representation
1227 STEPConstruct_UnitContext mk;
1229 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1230 shapeRep->SetName (new TCollection_HAsciiString(""));
1232 // Create SDR (only once for non-manifold group)
1233 if (!useExistingNMSSR) {
1234 SDR0->SetUsedRepresentation (shapeRep);
1235 // create binder for SR and attach to it binder for RepItem (if exists)
1236 Handle(Transfer_Binder) resbind = TransientResult(shapeRep);
1237 binder = FP->Find(start);
1238 if ( ! binder.IsNull() ) {
1239 resbind->AddResult ( binder );
1240 FP->Rebind(start,resbind);
1241 //binder->AddResult ( resbind );
1244 for(Standard_Integer k = 1; k <= aSeqBindRelation.Length(); k++)
1245 resbind->AddResult(aSeqBindRelation.Value(k));
1247 // Add SDR for non-manifold topology in group mode 0 (ssv; 18.11.2010)
1248 if ( !aNMBinder.IsNull() )
1249 resbind->AddResult(aNMBinder);
1252 } else return FP->Find(start);
1256 //=======================================================================
1257 //function : TransferCompound
1258 // #### TRANSFER COMPOUND AS (SUB-)ASSEMBLY
1260 //=======================================================================
1262 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(Transfer_Finder)& start,
1263 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1264 const Handle(Transfer_FinderProcess)& FP)
1266 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1267 Handle(Transfer_Binder) binder;
1268 if (mapper.IsNull()) return binder;
1269 TopoDS_Shape theShape = mapper->Value();
1271 // Inspect non-manifold topology case (ssv; 10.11.2010)
1272 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
1273 Standard_Boolean isManifold;
1275 isManifold = IsManifoldShape(theShape);
1277 isManifold = Standard_True;
1279 // get a sequence of components (subshapes)
1280 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
1281 // Prepare a collection for non-manifold group of shapes
1282 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
1283 // PTV OCC725 17.09.2002 -- begin --
1284 Standard_Integer nbFreeVrtx = 0;
1285 TopoDS_Compound aCompOfVrtx;
1287 aB.MakeCompound(aCompOfVrtx);
1291 cout << "Exploding Solids to Shells if any..." << endl;
1294 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1295 TopoDS_Shape aSubShape = iter.Value();
1296 if (aSubShape.ShapeType() != TopAbs_VERTEX) {
1298 // Store non-manifold topology as shells (ssv; 10.11.2010)
1299 if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
1300 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
1301 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
1302 aSubShell.Closed(Standard_True);
1303 RepItemSeq->Append(aSubShell);
1304 NonManifoldGroup->Append(aSubShell);
1307 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
1308 RepItemSeq->Append(aSubShape);
1309 NonManifoldGroup->Append(aSubShape);
1312 RepItemSeq->Append(aSubShape);
1316 aB.Add(aCompOfVrtx, iter.Value());
1320 RepItemSeq->Append (aCompOfVrtx);
1322 // PTV OCC725 17.09.2002 -- end --
1324 // Constitution : liste d axes, le premier est l origine, les suivants : 1
1326 Handle(StepShape_ShapeRepresentation) shapeRep =
1327 Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
1328 if ( shapeRep.IsNull() ) {
1329 shapeRep = new StepShape_ShapeRepresentation;
1330 SDR0->SetUsedRepresentation(shapeRep); // to be used by MakeItem
1332 binder = TransientResult(SDR0); // set SDR as first item in order to be found first (but not SDR of subshape!)
1333 binder->AddResult ( TransientResult(shapeRep) );
1335 // translate components
1336 Standard_Integer i, nbs = RepItemSeq->Length();
1337 Handle(TColStd_HSequenceOfTransient) ItemSeq = new TColStd_HSequenceOfTransient();
1338 ItemSeq->Append (myContext.GetDefaultAxis());
1339 myContext.NextLevel();
1340 for ( i = 1; i <= nbs; i ++) {
1341 Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper (FP,RepItemSeq->Value(i));
1342 Handle(StepGeom_Axis2Placement3d) AX1;
1344 Handle(Transfer_Binder) bnd = TransferSubShape(subs, SDR0, AX1, FP, NonManifoldGroup, isManifold);
1346 if (!AX1.IsNull()) ItemSeq->Append (AX1);
1347 // copy binders so as to have all roots in upper binder, but do not conflict
1348 while ( !bnd.IsNull() ) {
1349 Handle(Transfer_SimpleBinderOfTransient) bx =
1350 Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
1351 if ( !bx.IsNull() ) {
1352 // Single SDR is created for a non-manifold group (ssv: 12.11.2010)
1353 if (!isManifold && i > 1)
1356 binder->AddResult( TransientResult( bx->Result() ) );
1358 bnd = bnd->NextResult();
1361 myContext.PrevLevel();
1363 Standard_Integer nsub = ItemSeq->Length();
1364 Handle(StepRepr_HArray1OfRepresentationItem) items =
1365 new StepRepr_HArray1OfRepresentationItem(1,nsub);
1367 // initialize representation
1368 for (Standard_Integer rep = 1; rep <= nsub; rep++)
1369 items->SetValue(rep,GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep)));
1370 shapeRep->SetItems(items);
1371 Standard_Real Tol = UsedTolerance (mytoler,theShape);
1372 STEPConstruct_UnitContext mk;
1374 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1375 shapeRep->SetName (new TCollection_HAsciiString(""));
1378 // SDR0->SetUsedRepresentation (shapeRep);
1383 //=======================================================================
1384 //function : TransferSubShape
1386 //=======================================================================
1388 Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape (const Handle(Transfer_Finder)& start,
1389 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1390 Handle(StepGeom_Axis2Placement3d)& AX1,
1391 const Handle(Transfer_FinderProcess)& FP,
1392 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
1393 const Standard_Boolean isManifold)
1395 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1396 if (mapper.IsNull()) return NullResult();
1397 TopoDS_Shape shape = mapper->Value();
1399 // SHAPE EN POSITION VENANT D UN ASSEMBLAGE
1400 // Il faut alors distinguer la transformation de la shape meme
1401 // laquelle est consideree a l origine, puis transferee
1402 // A part, un item decrivant une occurence en position est cree
1403 // SINON, la shape est prise et transferee telle quelle
1404 TopoDS_Shape sh0 = shape;
1406 if ( GroupMode() >0) {
1407 TopLoc_Location shloc = shape.Location();
1408 aLoc = shloc.Transformation();
1409 TopLoc_Location shident;
1410 sh0.Location (shident);
1411 mapper = TransferBRep::ShapeMapper(FP,sh0);
1412 mapper->SameAttributes (start);
1415 Handle(Transfer_Binder) resbind = FP->Find(mapper);
1416 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
1417 // Handle(StepShape_ShapeRepresentation) resultat;
1418 STEPConstruct_Part SDRTool;
1420 // Already SDR and SR available : take them as are
1421 Standard_Boolean iasdr = FP->GetTypedTransient
1422 (resbind,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation),sdr);
1423 if ( iasdr ) SDRTool.ReadSDR ( sdr );
1425 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
1426 sdr = SDRTool.SDRValue();
1428 // resultat = GetCasted(StepShape_ShapeRepresentation,sdr->UsedRepresentation());
1430 // if shape itself not yet translated, do it now
1431 //:abv 20.05.02: see comment in TransferShape(): added "! iasdr ||"
1432 Handle(Transfer_Binder) resprod = TransientResult(sdr); //KA - OCC7141(skl 10.11.2004)
1433 if ( ! iasdr || resbind.IsNull() ) {
1434 resbind = TransferShape(mapper, sdr, FP, shapeGroup, isManifold);
1435 Handle(Transfer_Binder) oldbind = FP->Find ( mapper );
1436 if ( ! oldbind.IsNull() && !resbind.IsNull()) resbind->AddResult ( oldbind );
1437 FP->Bind (mapper,resbind);
1438 resprod=resbind; //KA - OCC7141(skl 10.11.2004)
1440 if (resprod.IsNull())
1443 // A new resbind may have been produced
1444 // DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);
1445 // if (restrans.IsNull()) return resbind;
1446 // FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
1447 // sdr->SetUsedRepresentation(resultat); // to be used by MakeItem
1449 // make location for assembly placement
1450 GeomToStep_MakeAxis2Placement3d mkax (aLoc);
1451 Handle(StepGeom_Axis2Placement3d) AxLoc = mkax.Value();
1454 // create assembly structures (CDSR, NAUO etc.)
1455 STEPConstruct_Assembly mkitem;
1456 mkitem.Init (sdr,SDR0,myContext.GetDefaultAxis(),AxLoc);
1457 mkitem.MakeRelationship ();
1458 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink ( mkitem );
1460 // add roots corresponding to assembly and product structures to binder
1461 //Handle(Transfer_Binder) resprod = resbind; //KA - OCC7141(skl 10.11.2004)
1462 //KA: we need only the current subshape in resprod, since the binder is copied
1463 // in Transfershape which calls Transfersubshape [ OCC7141(skl 10.11.2004) ]
1465 resprod->AddResult ( TransientResult ( SDRTool.SDRValue() ) );
1466 resbind->AddResult ( TransientResult ( SDRTool.SDRValue() ) ); //KA - OCC7141(skl 10.11.2004)
1467 roots->Append ( myContext.GetRootsForPart ( SDRTool ) );
1469 for ( Standard_Integer i=1; i <= roots->Length(); i++ ) {
1470 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
1471 resbind->AddResult ( TransientResult ( roots->Value(i) ) ); //KA - OCC7141(skl 10.11.2004)
1473 myContext.NextIndex();
1475 //FP->Bind (mapper,resprod); //KA - OCC7141(skl 10.11.2004)
1477 // abv 16.10.00: bind CDSR (et al) to located shape in order to be able to track instances
1478 if ( mapper != start ) {
1479 Handle(Transfer_Binder) bnd = FP->Find ( start );
1480 for ( Standard_Integer j=1; j <= roots->Length(); j++ )
1481 if ( bnd.IsNull() ) bnd = TransientResult ( roots->Value(j) );
1482 else bnd->AddResult ( TransientResult ( roots->Value(j) ) );
1483 FP->Bind ( start, bnd );