0024624: Lost word in license statement in source files
[occt.git] / src / STEPControl / STEPControl_ActorWrite.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 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>
21
22// Transfer
23#include <Transfer_SimpleBinderOfTransient.hxx>
24#include <gp_Ax2.hxx>
25#include <GeomToStep_MakeAxis2Placement3d.hxx>
26#include <StepGeom_Axis2Placement3d.hxx>
27
28#include <STEPConstruct_Part.hxx>
29#include <STEPConstruct_Assembly.hxx>
30#include <STEPConstruct_ContextTool.hxx>
31#include <STEPConstruct_UnitContext.hxx>
32
33// TransferShape
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>
44
45#include <TopoDS.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>
52
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>
70
71#include <TopExp_Explorer.hxx>
72#include <TColStd_HSequenceOfTransient.hxx>
73#include <TCollection_HAsciiString.hxx>
74
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>
82
83#include <ShapeExtend_Explorer.hxx>
84#include <ShapeAnalysis_ShapeTolerance.hxx>
85#include <Interface_MSG.hxx>
86#include <Interface_Static.hxx>
87
88#include <Interface_Macros.hxx>
89#include <TopTools_HSequenceOfShape.hxx>
90
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>
96
97#include <XSAlgo.hxx>
98#include <XSAlgo_AlgoContainer.hxx>
99#include <StepRepr_ShapeRepresentationRelationship.hxx>
100#include <Transfer_SequenceOfBinder.hxx>
101
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>
109
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>
117
118// ============================================================================
119// Function: DumpWhatIs
120// Purpose: Use it in DEB mode to dump your shapes
121// ============================================================================
122
498ce76b 123#ifdef DEB
7fd59977 124static void DumpWhatIs(const TopoDS_Shape& S) {
125
126 TopTools_MapOfShape aMapOfShape;
127 aMapOfShape.Add(S);
128 TopTools_ListOfShape aListOfShape;
129 aListOfShape.Append(S);
130 TopTools_ListIteratorOfListOfShape itL(aListOfShape);
131 Standard_Integer nbSolids = 0,
132 nbShells = 0,
133 nbOpenShells = 0,
134 nbFaces = 0,
135 nbWires = 0,
136 nbEdges = 0,
137 nbVertexes = 0;
138
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) )
144 continue;
145 aListOfShape.Append(aSubShape);
146 if (aSubShape.ShapeType() == TopAbs_SOLID)
147 nbSolids++;
148 if (aSubShape.ShapeType() == TopAbs_SHELL) {
149 if ( !aSubShape.Closed() )
150 nbOpenShells++;
151 nbShells++;
152 }
153 if (aSubShape.ShapeType() == TopAbs_FACE)
154 nbFaces++;
155 if (aSubShape.ShapeType() == TopAbs_WIRE)
156 nbWires++;
157 if (aSubShape.ShapeType() == TopAbs_EDGE)
158 nbEdges++;
159 if (aSubShape.ShapeType() == TopAbs_VERTEX)
160 nbVertexes++;
161 }
162 }
498ce76b 163
7fd59977 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;
7fd59977 172}
498ce76b 173#endif
7fd59977 174
175//=======================================================================
176// Function : IsManifoldShape
177// Purpose : Used to define whether the passed shape has manifold
178// topology or not
179//=======================================================================
180
181static Standard_Boolean IsManifoldShape(const TopoDS_Shape& theShape) {
182
183 Standard_Boolean aResult = Standard_True;
184
185 // Do not check nested Compounds
186 TopoDS_Compound aDirectShapes;
187 BRep_Builder aBrepBuilder;
188 aBrepBuilder.MakeCompound(aDirectShapes);
189
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);
195 }
196
197 #ifdef DEB
198 DumpWhatIs(aDirectShapes);
199 #endif
200
201 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
202 TopExp::MapShapesAndAncestors(aDirectShapes, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
203
204 Standard_Integer aNbEdges = aMapEdgeFaces.Extent();
205 #ifdef DEB
206 cout << "Checking whether the topology passed is manifold..." << endl;
207 #endif
208
209 // Check topology
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;
216 break;
217 }
218 }
219 }
220
221 #ifdef DEB
222 cout << "Check result: "
223 << (aResult ? "TRUE" : "FALSE") << endl;
224 #endif
225
226 return aResult;
227}
228
229/* this is a start of a comment! */
230#ifdef DEB
231void DumpBinder (const Handle(Transfer_Binder) &binder)
232{
233 Handle(Transfer_Binder) bbb = binder;
234 while ( ! bbb.IsNull() ) {
235 Handle(Transfer_SimpleBinderOfTransient) bx =
236 Handle(Transfer_SimpleBinderOfTransient)::DownCast ( bbb );
237 cout << (void*)&bx;
238 if ( ! bx.IsNull() ) {
239 cout << "--> " << bx->ResultTypeName() << " " << *(void**)&bx->Result() << endl;
240 }
241 else cout << "--> ???" << endl;
242 bbb = bbb->NextResult();
243 }
244 cout << endl;
245}
246#endif
247/* this is a end of a comment */
248
249//=======================================================================
250//function : STEPControl_ActorWrite
251//purpose :
252//=======================================================================
253
254STEPControl_ActorWrite::STEPControl_ActorWrite ()
255: mygroup (0) , mytoler (-1.)
256{
257 SetMode(STEPControl_ShellBasedSurfaceModel);
258}
259
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//=======================================================================
265
266Handle(StepShape_NonManifoldSurfaceShapeRepresentation) STEPControl_ActorWrite::getNMSSRForGroup(const Handle(TopTools_HSequenceOfShape)& shapeGroup,
267 const Handle(Transfer_FinderProcess)& FP,
268 Standard_Boolean& isNMSSRCreated) const
269{
270 Handle(StepShape_NonManifoldSurfaceShapeRepresentation) aResult;
271
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) )
277 break;
278 }
279 }
280
281 if ( aResult.IsNull() ) {
282 #ifdef DEB
283 cout << "\nNew NMSSR created" << endl;
284 #endif
285 aResult = new StepShape_NonManifoldSurfaceShapeRepresentation;
286 isNMSSRCreated = Standard_True;
287 } else {
288 #ifdef DEB
289 cout << "\nExisting NMSSR is used" << endl;
290 #endif
291 isNMSSRCreated = Standard_False;
292 }
293
294 return aResult;
295}
296
297
298//=======================================================================
299//function : SetMode
300//purpose :
301//=======================================================================
302
303void STEPControl_ActorWrite::SetMode (const STEPControl_StepModelType M)
304{
305 switch (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 !!
314 default: break;
315 }
316}
317
318//=======================================================================
319//function : Mode
320//purpose :
321//=======================================================================
322
323STEPControl_StepModelType STEPControl_ActorWrite::Mode () const
324{
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;
333 default : break;
334 }
335 return STEPControl_AsIs;
336}
337
338//=======================================================================
339//function : SetGroupMode
340//purpose :
341//=======================================================================
342
343void STEPControl_ActorWrite::SetGroupMode (const Standard_Integer mode)
344{
345 if (mode >= 0) mygroup = mode;
346}
347
348//=======================================================================
349//function : GroupMode
350//purpose :
351//=======================================================================
352
353Standard_Integer STEPControl_ActorWrite::GroupMode () const
354{
355 return mygroup;
356}
357
358//=======================================================================
359//function : SetTolerance
360//purpose :
361//=======================================================================
362
363void STEPControl_ActorWrite::SetTolerance (const Standard_Real Tol)
364{
365 mytoler = Tol;
366}
367
368//=======================================================================
369//function : Recognize
370// ATTENTION, Recognize doit s aligner sur ce que Transfer sait faire
371//purpose :
372//=======================================================================
373
374Standard_Boolean STEPControl_ActorWrite::Recognize (const Handle(Transfer_Finder)& start)
375{
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;
380
381 Standard_Boolean yasolid = Standard_False, yashell = Standard_False,
382 yaface = Standard_False;
383
384 TopoDS_Shape theShape, aShape;
385// theShape = TopoDSToStep::DirectFaces(mapper->Value());
386 theShape = mapper->Value(); // pour une reconnaissance c est bien assez
387
388 if (theShape.ShapeType() == TopAbs_COMPOUND) {
389
390 TopExp_Explorer SolidExp, ShellExp, FaceExp;
391
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;
398 }
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;
403// pour wireframe ?
404
405// Faceted : il est OBLIGATOIRE d avoir des surfaces support Plane et des
406// courbes 3D Line (pcurves ignorees)
407
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;
414 }
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;
420 }
421 }
422
423 switch (mymode) {
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
431 default : break;
432 }
433 return Standard_False;
434}
435
436
437// ######## MAKE PRODUCT DATA + CONTEXT ########
438
439//=======================================================================
440//function : Transfer
441//purpose :
442//=======================================================================
443
444Handle(Transfer_Binder) STEPControl_ActorWrite::Transfer (const Handle(Transfer_Finder)& start,
445 const Handle(Transfer_FinderProcess)& FP)
446{
447 XSAlgo::AlgoContainer()->PrepareForTransfer();
448
449 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
450
451 if (mapper.IsNull()) return NullResult();
452 TopoDS_Shape shape = mapper->Value();
453
454 // init context
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)
459
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");
c6541a0c 464 UnitsMethods::InitializeFactors ( lFactor, ( anglemode <= 1 ? 1. : M_PI/180. ), 1. );
7fd59977 465
466 // create SDR
467 STEPConstruct_Part SDRTool;
468 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
469 Handle(StepShape_ShapeDefinitionRepresentation) sdr = SDRTool.SDRValue();
470 // transfer shape
471
472 Handle(Transfer_Binder) resbind = TransferShape (mapper,sdr,FP);
473
474// Handle(StepShape_ShapeRepresentation) resultat;
475// FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
476// sdr->SetUsedRepresentation (resultat);
477
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);
484
485 // bind and exit
486 //FP->Bind (mapper,resprod);
487 myContext.NextIndex();
488 return resprod;
489}
490
491//==========================================
492
493static Standard_Real UsedTolerance (const Standard_Real mytoler,
494 const TopoDS_Shape& theShape)
495{
496
497 // COMPUTING 3D TOLERANCE
498 // Either from Session, or Computed (Least,Average, or Greatest)
499 // Then given to TopoDSToStep_Tool
500
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");
505 if (Tol <= 0) {
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 ...
510 }
511 if (Tol == 0) Tol = 1.e-07; // minimum ...
512
513 return Tol;
514}
515
516//=======================================================================
517//function : IsAssembly
518//purpose :
519//=======================================================================
520// if GroupMode is >1 downgrades all compounds having single subshape to that
521// subshape
522
523Standard_Boolean STEPControl_ActorWrite::IsAssembly (TopoDS_Shape &S) const
524{
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;
533 break;
534 }
535 }
536 if ( IsOnlyVertices )
537 return Standard_False;
538 }
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();
543 it.Next();
544 if ( it.More() ) return Standard_True;
545 S = shape;
546 return IsAssembly ( S );
547}
548
549//=======================================================================
550//function : TransferShape
551//purpose :
552//=======================================================================
553
554/*
555static void UpdateMap (const TopoDS_Shape &shape,
556 BRepTools_Modifier &M1,
557 BRepTools_Modifier &M2,
558 const Handle(Transfer_FinderProcess) &FinderProcess)
559{
560 TopoDS_Shape S = M1.ModifiedShape ( shape );
561 S = M2.ModifiedShape ( S );
562 if ( S == shape ) return;
563
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 );
569 }
570
571 for ( TopoDS_Iterator it(shape); it.More(); it.Next() )
572 UpdateMap ( it.Value(), M1, M2, FinderProcess );
573}
574*/
575
576// PTV 16.09.2002 added for transfering vertices.
577static Standard_Boolean transferVertex (const Handle(Transfer_FinderProcess)& FP,
578 Handle(StepShape_HArray1OfGeometricSetSelect)& aGSS,
579 const TopoDS_Shape& aShVrtx,
580 const Standard_Integer theNum)
581{
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 );
586
587 if (!aMkVrtx.IsDone())
588 return IsDone;
589
590 Handle(StepShape_VertexPoint) aVP =
591 Handle(StepShape_VertexPoint)::DownCast(aTool.Find(aShVrtx));
592 if (aVP.IsNull())
593 return IsDone;
594
595 StepShape_GeometricSetSelect select;
596 select.SetValue(aVP->VertexGeometry());
597 // add current result
598 aGSS->SetValue( theNum, select );
599 IsDone = Standard_True;
600 return IsDone;
601}
602
603
604Handle(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)
609{
610 STEPControl_StepModelType mymode = Mode();
611 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
612 Handle(Transfer_Binder) binder;
613
614 // Indicates whether to use an exising NMSSR to write items to (ss; 13.11.2010)
615 Standard_Boolean useExistingNMSSR = Standard_False;
616
617 if (mapper.IsNull()) return binder;
618 TopoDS_Shape theShape = mapper->Value();
619
620 if (theShape.IsNull()) return binder;
621
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
629#ifdef DEB
630 cout << "Warning: STEPControl_ActorWrite::TransferShape(): shape already translated" << endl;
631#endif
632// return binder;
633 }
634
635 // MODE ASSEMBLY : if Compound, (sub-)assembly
636 if ( IsAssembly(theShape) )
637 return TransferCompound(start, SDR0, FP);
638
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;
646
647 // Create empty Compounds
648 brepBuilder.MakeCompound(aManifoldCompound);
649 brepBuilder.MakeCompound(aNMCompound);
650
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;
654
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;
660 }
661 else {
662 TopTools_ListOfShape aListOfShapes;
663 TopTools_ListOfShape aListOfManifoldShapes;
664 aListOfShapes.Append(theShape);
665
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);
676 else
677 aListOfManifoldShapes.Append(aSubShape);
678 }
679 }
680
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);
687 }
688
689 }
690
691 // Process only manifold topology in the current TransferShape invocation.
692 // Invoke TransferShape for non-manifold topology separately (see below)
693 theShape = aManifoldCompound;
694
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();
699
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);
709 }
710 }
711 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
712 RepItemSeq->Append(aSubShape);
713 NonManifoldGroup->Append(aSubShape);
714 }
715 else
716 RepItemSeq->Append( iter.Value() );
717 }
718
719 Standard_Integer aNMItemsNb = RepItemSeq->Length();
720
721 // In case of pure manifold topology do nothing; theShape is processed as usual (see below)
722 if (aNMItemsNb > 0) {
723
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)
727 // is used
728 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
729 if (isOnlyNonManifold)
730 sdr = SDR0;
731 else {
732 STEPConstruct_Part SDRTool;
733 SDRTool.MakeSDR( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
734 sdr = SDRTool.SDRValue();
735 }
736
737 aNMBinder = TransientResult(sdr);
738
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);
745 }
746
747 // Nothing else needed for pure non-manifold topology, return
748 if (isOnlyNonManifold)
749 return aNMBinder;
750
751 }
752
753 }
754 // [END] Separate manifold topology from non-manifold in group mode 0 (ssv; 18.11.2010)
755
756 // create a list of items to translate
757 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
758
759 // PTV 16.09.2002 OCC725 separate shape from solo vertices.
66d6976f 760 Standard_Boolean isOnlyVertices = Standard_False;
7fd59977 761 if (theShape.ShapeType() == TopAbs_COMPOUND) {
762 Standard_Integer countVrtx = 0;
763 Standard_Integer countSh = 0;
764 TopoDS_Compound aNewShape, aCompOfVrtx;
765 BRep_Builder aB;
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);
773 countSh++;
774 }
775 else {
776 aB.Add(aCompOfVrtx, aCurSh);
777 countVrtx++;
778 }
779 }
780 // replace the shapes
781 if (countSh)
782 theShape = aNewShape;
783 if (countVrtx)
784 RepItemSeq->Append(aCompOfVrtx);
66d6976f 785 if (countSh == 0)
786 isOnlyVertices = Standard_True;
7fd59977 787 }
7fd59977 788
7fd59977 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()));
795 }
796 for (ShellExp.Init(theShape, TopAbs_SHELL, TopAbs_SOLID);
797 ShellExp.More();ShellExp.Next()) {
798 RepItemSeq->Append(TopoDS::Shell(ShellExp.Current()));
799 }
800
801 for (FaceExp.Init(theShape, TopAbs_FACE, TopAbs_SHELL);
802 FaceExp.More();FaceExp.Next()) {
803 RepItemSeq->Append(TopoDS::Face(FaceExp.Current()));
804 }
805 }
806 else {
66d6976f 807 if (!isOnlyVertices)
808 RepItemSeq->Append(theShape); //:j1
7fd59977 809 }
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()));
818 }
819
820 }
821 else if (theShape.ShapeType() == TopAbs_SOLID) {
822 RepItemSeq->Append(TopoDS::Solid(theShape));
823 }
824 else if (theShape.ShapeType() == TopAbs_SHELL) {
825 RepItemSeq->Append(TopoDS::Shell(theShape));
826 }
827 else if (theShape.ShapeType() == TopAbs_FACE) {
828 RepItemSeq->Append(TopoDS::Face(theShape));
829 }
830 else if (mymode != STEPControl_GeometricCurveSet && mymode != STEPControl_AsIs) {
831 FP->AddFail(start,"The Shape is not a SOLID, nor a SHELL, nor a FACE");
832 return binder;
833 }
834 else RepItemSeq->Append (theShape);
835
836 // COMPUTING 3D TOLERANCE
837 // Either from Session, or Computed (Least,Average, or Greatest)
838 // Then given to TopoDSToStep_Tool
839 Standard_Real Tol = UsedTolerance (mytoler,theShape);
840
841 // Create a STEP-Entity for each TopoDS_Shape
842 // according to the current StepModelMode
843
844 Standard_Integer nbs = RepItemSeq->Length();
845 Handle(TColStd_HSequenceOfTransient) ItemSeq =
846 new TColStd_HSequenceOfTransient();
847
848//ptv 10.11.00: allow to write empty Compound: if (GroupMode() >0)
849 ItemSeq->Append (myContext.GetDefaultAxis());
850 STEPControl_StepModelType trmode = mymode;
851 for (Standard_Integer i = 1; i <= nbs; i++) {
852 TopoDS_Shape xShape = RepItemSeq->Value(i);
853
854 if(mymode == STEPControl_AsIs) {
855 switch(xShape.ShapeType()) {
856 case TopAbs_SOLID : trmode = STEPControl_ManifoldSolidBrep;break;
857 case TopAbs_SHELL : trmode = STEPControl_ShellBasedSurfaceModel; break;
858 case TopAbs_FACE : trmode = STEPControl_ShellBasedSurfaceModel;break;
859 default : trmode =STEPControl_GeometricCurveSet; break;
860 }
861 }
862 //:abv 24Jan99 CAX-IF TRJ3: expanded Shape Processing
863// TopoDS_Shape aShape = xShape;
864 // eliminate conical surfaces with negative semiangles
865// Handle(TopoDSToStep_ConicalSurfModif) CSM = new TopoDSToStep_ConicalSurfModif();
866// BRepTools_Modifier CSMT(aShape,CSM);
867// if ( CSMT.IsDone() ) aShape = CSMT.ModifiedShape ( aShape );
868// // eliminate indirect elementary surfaces
869// Handle(TopoDSToStep_DirectModification) DM = new TopoDSToStep_DirectModification();
870// BRepTools_Modifier DMT(aShape,DM);
871// if ( DMT.IsDone() ) aShape = DMT.ModifiedShape ( aShape );
872//// aShape = TopoDSToStep::DirectFaces(xShape);
873 Handle(Standard_Transient) info;
874 Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
875
876 // Fix only manifold shapes, do nothing with non-manifold topology as it is processed separately (ssv; 13.11.2010)
877 TopoDS_Shape aShape;
878 if (isManifold)
879 aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol,
880 "write.step.resource.name",
b485ee79
KD
881 "write.step.sequence", info,
882 FP->GetProgress() );
7fd59977 883 else
884 aShape = xShape;
885
886 // create a STEP entity corresponding to shape
887 Handle(StepGeom_GeometricRepresentationItem) item;
888 switch (trmode)
889 {
890 case STEPControl_ManifoldSolidBrep:
891 {
892 if (aShape.ShapeType() == TopAbs_SOLID) {
893 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
894
895 //:d6 abv 13 Mar 98: if solid has more than 1 shell,
896 // try to treat it as solid with voids
897 Standard_Integer nbShells = 0;
898 for ( TopoDS_Iterator It ( aSolid ); It.More(); It.Next() )
899 if (It.Value().ShapeType() == TopAbs_SHELL) nbShells++;
900 if ( nbShells >1 ) {
901 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
902 MkBRepWithVoids.Tolerance() = Tol;
903 if (MkBRepWithVoids.IsDone()) {
904 item = MkBRepWithVoids.Value();
905 }
906 else nbShells = 1; //smth went wrong; let it will be just Manifold
907 }
908 if ( nbShells ==1 ) {
909
910 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aSolid,FP);
911 MkManifoldSolidBrep.Tolerance() = Tol;
912 if (MkManifoldSolidBrep.IsDone()) {
913 item = MkManifoldSolidBrep.Value();
914 }
915 }
916 }
917 else if (aShape.ShapeType() == TopAbs_SHELL) {
918 TopoDS_Shell aShell = TopoDS::Shell(aShape);
919 TopoDSToStep_MakeManifoldSolidBrep MkManifoldSolidBrep(aShell,FP);
920 MkManifoldSolidBrep.Tolerance() = Tol;
921 if (MkManifoldSolidBrep.IsDone()) {
922 item = MkManifoldSolidBrep.Value();
923 }
924 }
925 break;
926 }
927 case STEPControl_BrepWithVoids:
928 {
929 if (aShape.ShapeType() == TopAbs_SOLID) {
930 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
931 TopoDSToStep_MakeBrepWithVoids MkBRepWithVoids(aSolid,FP);
932 MkBRepWithVoids.Tolerance() = Tol;
933 if (MkBRepWithVoids.IsDone()) {
934 item = MkBRepWithVoids.Value();
935 }
936 }
937 break;
938 }
939 case STEPControl_FacetedBrep:
940 {
941 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
942 if (facErr != TopoDSToStep_FacetedDone) {
943 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
944 if (facErr == TopoDSToStep_SurfaceNotPlane) {
945 FP->AddFail(start,"-- The TopoDS_Face is not plane");
946 }
947 else if (facErr == TopoDSToStep_PCurveNotLinear) {
948 FP->AddFail(start,"-- The Face contains non linear PCurves");
949 }
950 return binder;
951 }
952 if (aShape.ShapeType() == TopAbs_SOLID) {
953 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
954 TopoDSToStep_MakeFacetedBrep MkFacetedBrep(aSolid,FP);
955 MkFacetedBrep.Tolerance() = Tol;
956 if (MkFacetedBrep.IsDone()) {
957 item = MkFacetedBrep.Value();
958 }
959 }
960 break;
961 }
962 case STEPControl_FacetedBrepAndBrepWithVoids:
963 {
964 TopoDSToStep_FacetedError facErr = TopoDSToStep_FacetedTool::CheckTopoDSShape(aShape);
965 if (facErr != TopoDSToStep_FacetedDone) {
966 FP->AddFail(start,"Error in Faceted Shape from TopoDS");
967 if (facErr == TopoDSToStep_SurfaceNotPlane) {
968 FP->AddFail(start,"-- The TopoDS_Face is not plane");
969 }
970 else if (facErr == TopoDSToStep_PCurveNotLinear) {
971 FP->AddFail(start,"-- The Face contains non linear PCurves");
972 }
973 return binder;
974 }
975 if (aShape.ShapeType() == TopAbs_SOLID) {
976 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
977 TopoDSToStep_MakeFacetedBrepAndBrepWithVoids
978 MkFacetedBrepAndBrepWithVoids(aSolid,FP);
979 MkFacetedBrepAndBrepWithVoids.Tolerance() = Tol;
980 if (MkFacetedBrepAndBrepWithVoids.IsDone()) {
981 item = MkFacetedBrepAndBrepWithVoids.Value();
982 }
983 }
984 break;
985 }
986 case STEPControl_ShellBasedSurfaceModel:
987 {
988 if (aShape.ShapeType() == TopAbs_SOLID) {
989 TopoDS_Solid aSolid = TopoDS::Solid(aShape);
990 TopoDSToStep_MakeShellBasedSurfaceModel
991 MkShellBasedSurfaceModel(aSolid, FP);
992 MkShellBasedSurfaceModel.Tolerance() = Tol;
993 if (MkShellBasedSurfaceModel.IsDone()) {
994 item = MkShellBasedSurfaceModel.Value();
995 }
996 }
997 else if (aShape.ShapeType() == TopAbs_SHELL) {
998 TopoDS_Shell aShell = TopoDS::Shell(aShape);
999 // Non-manifold topology is stored via NMSSR containing series of SBSM (ssv; 13.11.2010)
1000 TopoDSToStep_MakeShellBasedSurfaceModel MkShellBasedSurfaceModel(aShell, FP);
1001 MkShellBasedSurfaceModel.Tolerance() = Tol;
1002 if (MkShellBasedSurfaceModel.IsDone()) {
1003 item = MkShellBasedSurfaceModel.Value();
1004 }
1005 }
1006 else if (aShape.ShapeType() == TopAbs_FACE) {
1007 TopoDS_Face aFace = TopoDS::Face(aShape);
1008 TopoDSToStep_MakeShellBasedSurfaceModel
1009 MkShellBasedSurfaceModel(aFace, FP);
1010 MkShellBasedSurfaceModel.Tolerance() = Tol;
1011 if (MkShellBasedSurfaceModel.IsDone()) {
1012 item = MkShellBasedSurfaceModel.Value();
1013 }
1014 }
1015 break;
1016 }
1017 case STEPControl_GeometricCurveSet:
1018 {
1019 TopoDSToStep_MakeGeometricCurveSet MkGeometricCurveSet(aShape,FP);
1020 MkGeometricCurveSet.Tolerance() = Tol;
1021 if (MkGeometricCurveSet.IsDone()) {
1022 item = MkGeometricCurveSet.Value();
1023 }
1024 // PTV 22.08.2002 OCC609 ------------------------- begin --------------------
1025 // modified by PTV 16.09.2002 OCC725
1026 else if (aShape.ShapeType() == TopAbs_COMPOUND ||
1027 aShape.ShapeType() == TopAbs_VERTEX) {
1028 // it is compund with solo vertices.
1029 Standard_Integer aNbVrtx = 0;
1030 Standard_Integer curNb = 0;
1031 TopExp_Explorer anExp (aShape, TopAbs_VERTEX);
1032 for ( ; anExp.More(); anExp.Next() ) {
1033 if ( anExp.Current().ShapeType() != TopAbs_VERTEX )
1034 continue;
1035 aNbVrtx++;
1036 }
1037 if ( aNbVrtx ) {
1038 // create new geometric curve set for all vertices
1039 Handle(StepShape_HArray1OfGeometricSetSelect) aGSS =
1040 new StepShape_HArray1OfGeometricSetSelect(1,aNbVrtx);
1041 Handle(TCollection_HAsciiString) empty = new TCollection_HAsciiString("");
1042 Handle(StepShape_GeometricCurveSet) aGCSet =
1043 new StepShape_GeometricCurveSet;
1044 aGCSet->SetName(empty);
1045 // iterates on compound with vertices and trances each vertex
1046 for ( anExp.ReInit() ; anExp.More(); anExp.Next() ) {
1047 TopoDS_Shape aVertex = anExp.Current();
1048 if ( aVertex.ShapeType() != TopAbs_VERTEX )
1049 continue;
1050 curNb++;
1051 transferVertex (FP, aGSS, aVertex, curNb);
1052 } // end of iteration on compound with vertices.
1053 aGCSet->SetElements(aGSS);
1054 item = aGCSet;
1055 } // end of check that number of vertices is not null
1056 }
1057 // PTV 22.08.2002 OCC609------------------------- end --------------------
1058 break;
1059 }
1060 default: break;
1061 }
1062 if ( item.IsNull() ) continue;
1063
1064 // add resulting item to the FP
1065 ItemSeq->Append(item);
1066 Handle(TransferBRep_ShapeMapper) submapper;
1067 if ( xShape.IsSame ( mapper->Value() ) )
1068 submapper = Handle(TransferBRep_ShapeMapper)::DownCast ( start );
1069 if ( submapper.IsNull() ) submapper = TransferBRep::ShapeMapper (FP,xShape);
1070 Handle(Transfer_Binder) subbind = FP->Find ( submapper );
1071 if ( subbind.IsNull() ) {
1072 subbind = TransientResult ( item );
1073 FP->Bind ( submapper, subbind );
1074 }
1075 else subbind->AddResult ( TransientResult ( item ) );
1076
1077 //:abv 24Jan99 CAX-IF TRJ3: Update FinderProcess map to take into account shape processing
1078// UpdateMap ( xShape, CSMT, DMT, FP );
1079 XSAlgo::AlgoContainer()->MergeTransferInfo(FP, info);
1080 }
1081
1082 // - Make Shape Representation
1083 Standard_Integer nCc1 = ItemSeq->Length();
1084 if (nCc1 < 1) {
1085 FP->AddFail(start,"The Shape has not the appropriate type");
1086 return binder;
1087 }
1088 Handle(StepShape_ShapeRepresentation) shapeRep;
1089 if ( theShape.ShapeType() == TopAbs_SHAPE ) { // for external references
1090 shapeRep = new StepShape_ShapeRepresentation;
1091 }
1092 else {
1093 switch (mymode) {
1094 case STEPControl_ManifoldSolidBrep:
1095 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1096 break;
1097 case STEPControl_FacetedBrep:
1098 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1099 break;
1100 // NOTE: STEPControl_AsIs mode is normally used to transfer non-manifold topology.
1101 // However, as ShellBasedSurfaceModel is used in non-manifold processing
1102 // internally, STEPControl_ShellBasedSurfaceModel is also adjusted to
1103 // be able to work with non-manifold cases
1104 case STEPControl_ShellBasedSurfaceModel:
1105 if (isManifold)
1106 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1107 else {
1108 Standard_Boolean isNewNMSSRCreated;
1109 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1110 useExistingNMSSR = !isNewNMSSRCreated;
1111 }
1112 break;
1113 case STEPControl_GeometricCurveSet:
1114 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1115 break;
1116 case STEPControl_AsIs :
1117 {
1118 if(nbs == 1) {
1119 if(trmode == STEPControl_ManifoldSolidBrep)
1120 shapeRep = new StepShape_AdvancedBrepShapeRepresentation;
1121 else if(trmode == STEPControl_ShellBasedSurfaceModel)
1122 // Process non-manifold topology separately (ssv; 13.11.2010)
1123 if (isManifold)
1124 shapeRep = new StepShape_ManifoldSurfaceShapeRepresentation;
1125 else {
1126 Standard_Boolean isNewNMSSRCreated;
1127 shapeRep = this->getNMSSRForGroup(shapeGroup, FP, isNewNMSSRCreated);
1128 useExistingNMSSR = !isNewNMSSRCreated;
1129 }
1130 else if(trmode == STEPControl_GeometricCurveSet)
1131 shapeRep = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1132 else if(trmode ==STEPControl_FacetedBrep)
1133 shapeRep = new StepShape_FacetedBrepShapeRepresentation;
1134 }
1135 else shapeRep = new StepShape_ShapeRepresentation;
1136 }
1137 break;
1138 default: break;
1139 }
1140 }
1141 if(shapeRep.IsNull()) {
1142 Handle(Transfer_Binder) resb;
1143 return resb;
1144 }
1145
1146 Handle(StepRepr_HArray1OfRepresentationItem) items =
1147 new StepRepr_HArray1OfRepresentationItem(1,nCc1);
1148
1149 for (Standard_Integer rep = 1; rep <= nCc1; rep++) {
1150 Handle(StepRepr_RepresentationItem) repit =
1151 GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep));
1152 items->SetValue(rep,repit);
1153 }
1154 Standard_Integer ap = Interface_Static::IVal("write.step.schema");
1155 Transfer_SequenceOfBinder aSeqBindRelation;
1156 if(ap == 3 && nbs > 1) {
1157 Standard_Integer j = 1;
1158 if(items->Value(j)->IsKind(STANDARD_TYPE(StepGeom_Axis2Placement3d))) {
1159 Handle(StepRepr_HArray1OfRepresentationItem) axis =
1160 new StepRepr_HArray1OfRepresentationItem(1,1);
1161 axis->SetValue(1,items->Value(j++));
1162 shapeRep->SetItems(axis);
1163 }
1164 for (; j <= items->Length(); j++) {
1165
1166 Handle(StepShape_ShapeRepresentation) ShapeRepr1;
1167 if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ManifoldSolidBrep)))
1168 ShapeRepr1 = new StepShape_AdvancedBrepShapeRepresentation;
1169 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_ShellBasedSurfaceModel)))
1170 ShapeRepr1 = new StepShape_ManifoldSurfaceShapeRepresentation;
1171 else if(items->Value(j)->IsKind(STANDARD_TYPE(StepShape_GeometricCurveSet)))
1172 ShapeRepr1 = new StepShape_GeometricallyBoundedWireframeShapeRepresentation;
1173 else if (items->Value(j)->IsKind(STANDARD_TYPE(StepShape_FacetedBrep)))
1174 ShapeRepr1 = new StepShape_FacetedBrepShapeRepresentation;
1175 else ShapeRepr1 = new StepShape_ShapeRepresentation;
1176
1177 Handle(StepRepr_HArray1OfRepresentationItem) repr1 = new StepRepr_HArray1OfRepresentationItem(1,2);
1178 repr1->SetValue(1,myContext.GetDefaultAxis());
1179 repr1->SetValue(2,items->Value(j));
1180 ShapeRepr1->SetItems(repr1);
1181 STEPConstruct_UnitContext mk1;
1182 mk1.Init(Tol);
1183 ShapeRepr1->SetContextOfItems(mk1.Value()); // la tolerance, voir au debut
1184 ShapeRepr1->SetName (new TCollection_HAsciiString(""));
1185
1186 Handle(StepRepr_ShapeRepresentationRelationship) aShapeRel = new StepRepr_ShapeRepresentationRelationship;
1187 Handle(TCollection_HAsciiString) aName = new TCollection_HAsciiString("");
1188 Handle(TCollection_HAsciiString) aDescr = new TCollection_HAsciiString("");
1189 aShapeRel->SetName(aName);
1190 aShapeRel->SetDescription(aDescr);
1191 aShapeRel->SetRep2(shapeRep);
1192 aShapeRel->SetRep1(ShapeRepr1);
1193
1194 aSeqBindRelation.Append(TransientResult (aShapeRel));
1195 }
1196 }
1197 else {
1198 if (!useExistingNMSSR)
1199 shapeRep->SetItems(items);
1200 else {
1201 // Add new representation item to the NMSSR's existing collection (ssv; 13.11.2010)
1202 Handle(StepRepr_HArray1OfRepresentationItem) oldItems = shapeRep->Items();
1203 Handle(StepRepr_HArray1OfRepresentationItem) newItems =
1204 new StepRepr_HArray1OfRepresentationItem(1, oldItems->Length() + 1);
1205 Standard_Integer el = 1;
1206 for (Standard_Integer i = 1; i <= oldItems->Length(); i++)
1207 newItems->SetValue( el++, oldItems->Value(i) );
1208 newItems->SetValue( el, items->Value( items->Length() ) );
1209 shapeRep->SetItems(newItems);
1210 }
1211 }
1212
1213 // init representation
1214 STEPConstruct_UnitContext mk;
1215 mk.Init(Tol);
1216 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1217 shapeRep->SetName (new TCollection_HAsciiString(""));
1218
1219 // Create SDR (only once for non-manifold group)
1220 if (!useExistingNMSSR) {
1221 SDR0->SetUsedRepresentation (shapeRep);
1222 // create binder for SR and attach to it binder for RepItem (if exists)
1223 Handle(Transfer_Binder) resbind = TransientResult(shapeRep);
1224 binder = FP->Find(start);
1225 if ( ! binder.IsNull() ) {
1226 resbind->AddResult ( binder );
1227 FP->Rebind(start,resbind);
1228 //binder->AddResult ( resbind );
1229 //resbind = binder;
1230 }
1231 for(Standard_Integer k = 1; k <= aSeqBindRelation.Length(); k++)
1232 resbind->AddResult(aSeqBindRelation.Value(k));
1233
1234 // Add SDR for non-manifold topology in group mode 0 (ssv; 18.11.2010)
1235 if ( !aNMBinder.IsNull() )
1236 resbind->AddResult(aNMBinder);
1237
1238 return resbind;
1239 } else return FP->Find(start);
1240
1241}
1242
1243//=======================================================================
1244//function : TransferCompound
1245// #### TRANSFER COMPOUND AS (SUB-)ASSEMBLY
1246//purpose :
1247//=======================================================================
1248
1249Handle(Transfer_Binder) STEPControl_ActorWrite::TransferCompound (const Handle(Transfer_Finder)& start,
1250 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1251 const Handle(Transfer_FinderProcess)& FP)
1252{
1253 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1254 Handle(Transfer_Binder) binder;
1255 if (mapper.IsNull()) return binder;
1256 TopoDS_Shape theShape = mapper->Value();
1257
1258 // Inspect non-manifold topology case (ssv; 10.11.2010)
1259 Standard_Boolean isNMMode = Interface_Static::IVal("write.step.nonmanifold");
1260 Standard_Boolean isManifold;
1261 if (isNMMode)
1262 isManifold = IsManifoldShape(theShape);
1263 else
1264 isManifold = Standard_True;
1265
1266 // get a sequence of components (subshapes)
1267 Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
1268 // Prepare a collection for non-manifold group of shapes
1269 Handle(TopTools_HSequenceOfShape) NonManifoldGroup = new TopTools_HSequenceOfShape();
1270 // PTV OCC725 17.09.2002 -- begin --
1271 Standard_Integer nbFreeVrtx = 0;
1272 TopoDS_Compound aCompOfVrtx;
1273 BRep_Builder aB;
1274 aB.MakeCompound(aCompOfVrtx);
1275
1276 #ifdef DEB
1277 if (!isManifold)
1278 cout << "Exploding Solids to Shells if any..." << endl;
1279 #endif
1280
1281 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1282 TopoDS_Shape aSubShape = iter.Value();
1283 if (aSubShape.ShapeType() != TopAbs_VERTEX) {
1284
1285 // Store non-manifold topology as shells (ssv; 10.11.2010)
1286 if (!isManifold && aSubShape.ShapeType() == TopAbs_SOLID) {
1287 for ( TopoDS_Iterator aSubIter(aSubShape); aSubIter.More(); aSubIter.Next() ) {
1288 TopoDS_Shell aSubShell = TopoDS::Shell( aSubIter.Value() );
1289 aSubShell.Closed(Standard_True);
1290 RepItemSeq->Append(aSubShell);
1291 NonManifoldGroup->Append(aSubShell);
1292 }
1293 }
1294 else if (!isManifold && (aSubShape.ShapeType() == TopAbs_SHELL) ) {
1295 RepItemSeq->Append(aSubShape);
1296 NonManifoldGroup->Append(aSubShape);
1297 }
1298 else
1299 RepItemSeq->Append(aSubShape);
1300
1301 continue;
1302 }
1303 aB.Add(aCompOfVrtx, iter.Value());
1304 nbFreeVrtx++;
1305 }
1306 if (nbFreeVrtx)
1307 RepItemSeq->Append (aCompOfVrtx);
1308
1309 // PTV OCC725 17.09.2002 -- end --
1310
1311 // Constitution : liste d axes, le premier est l origine, les suivants : 1
1312 // par sous-item
1313 Handle(StepShape_ShapeRepresentation) shapeRep =
1314 Handle(StepShape_ShapeRepresentation)::DownCast(SDR0->UsedRepresentation());
1315 if ( shapeRep.IsNull() ) {
1316 shapeRep = new StepShape_ShapeRepresentation;
1317 SDR0->SetUsedRepresentation(shapeRep); // to be used by MakeItem
1318 }
1319 binder = TransientResult(SDR0); // set SDR as first item in order to be found first (but not SDR of subshape!)
1320 binder->AddResult ( TransientResult(shapeRep) );
1321
1322 // translate components
1323 Standard_Integer i, nbs = RepItemSeq->Length();
1324 Handle(TColStd_HSequenceOfTransient) ItemSeq = new TColStd_HSequenceOfTransient();
1325 ItemSeq->Append (myContext.GetDefaultAxis());
1326 myContext.NextLevel();
1327 for ( i = 1; i <= nbs; i ++) {
1328 Handle(TransferBRep_ShapeMapper) subs = TransferBRep::ShapeMapper (FP,RepItemSeq->Value(i));
1329 Handle(StepGeom_Axis2Placement3d) AX1;
1330
1331 Handle(Transfer_Binder) bnd = TransferSubShape(subs, SDR0, AX1, FP, NonManifoldGroup, isManifold);
1332
1333 if (!AX1.IsNull()) ItemSeq->Append (AX1);
1334 // copy binders so as to have all roots in upper binder, but do not conflict
1335 while ( !bnd.IsNull() ) {
1336 Handle(Transfer_SimpleBinderOfTransient) bx =
1337 Handle(Transfer_SimpleBinderOfTransient)::DownCast(bnd);
eafb234b 1338 if ( !bx.IsNull() ) {
7fd59977 1339 // Single SDR is created for a non-manifold group (ssv: 12.11.2010)
1340 if (!isManifold && i > 1)
1341 break;
1342 else
1343 binder->AddResult( TransientResult( bx->Result() ) );
eafb234b 1344 }
7fd59977 1345 bnd = bnd->NextResult();
1346 }
1347 }
1348 myContext.PrevLevel();
1349
1350 Standard_Integer nsub = ItemSeq->Length();
1351 Handle(StepRepr_HArray1OfRepresentationItem) items =
1352 new StepRepr_HArray1OfRepresentationItem(1,nsub);
1353
1354 // initialize representation
1355 for (Standard_Integer rep = 1; rep <= nsub; rep++)
1356 items->SetValue(rep,GetCasted(StepRepr_RepresentationItem, ItemSeq->Value(rep)));
1357 shapeRep->SetItems(items);
1358 Standard_Real Tol = UsedTolerance (mytoler,theShape);
1359 STEPConstruct_UnitContext mk;
1360 mk.Init(Tol);
1361 shapeRep->SetContextOfItems(mk.Value()); // la tolerance, voir au debut
1362 shapeRep->SetName (new TCollection_HAsciiString(""));
1363
1364 // set it to SDR
1365// SDR0->SetUsedRepresentation (shapeRep);
1366
1367 return binder;
1368}
1369
1370//=======================================================================
1371//function : TransferSubShape
1372//purpose :
1373//=======================================================================
1374
1375Handle(Transfer_Binder) STEPControl_ActorWrite::TransferSubShape (const Handle(Transfer_Finder)& start,
1376 const Handle(StepShape_ShapeDefinitionRepresentation)& SDR0,
1377 Handle(StepGeom_Axis2Placement3d)& AX1,
1378 const Handle(Transfer_FinderProcess)& FP,
1379 const Handle(TopTools_HSequenceOfShape)& shapeGroup,
1380 const Standard_Boolean isManifold)
1381{
1382 Handle(TransferBRep_ShapeMapper) mapper = Handle(TransferBRep_ShapeMapper)::DownCast(start);
1383 if (mapper.IsNull()) return NullResult();
1384 TopoDS_Shape shape = mapper->Value();
1385
1386 // SHAPE EN POSITION VENANT D UN ASSEMBLAGE
1387 // Il faut alors distinguer la transformation de la shape meme
1388 // laquelle est consideree a l origine, puis transferee
1389 // A part, un item decrivant une occurence en position est cree
1390 // SINON, la shape est prise et transferee telle quelle
1391 TopoDS_Shape sh0 = shape;
1392 gp_Trsf aLoc;
1393 if ( GroupMode() >0) {
1394 TopLoc_Location shloc = shape.Location();
1395 aLoc = shloc.Transformation();
1396 TopLoc_Location shident;
1397 sh0.Location (shident);
1398 mapper = TransferBRep::ShapeMapper(FP,sh0);
1399 mapper->SameAttributes (start);
1400 }
1401
1402 Handle(Transfer_Binder) resbind = FP->Find(mapper);
1403 Handle(StepShape_ShapeDefinitionRepresentation) sdr;
1404// Handle(StepShape_ShapeRepresentation) resultat;
1405 STEPConstruct_Part SDRTool;
1406
1407 // Already SDR and SR available : take them as are
1408 Standard_Boolean iasdr = FP->GetTypedTransient
1409 (resbind,STANDARD_TYPE(StepShape_ShapeDefinitionRepresentation),sdr);
1410 if ( iasdr ) SDRTool.ReadSDR ( sdr );
1411 else {
1412 SDRTool.MakeSDR ( 0, myContext.GetProductName(), myContext.GetAPD()->Application() );
1413 sdr = SDRTool.SDRValue();
1414 }
1415// resultat = GetCasted(StepShape_ShapeRepresentation,sdr->UsedRepresentation());
1416
1417 // if shape itself not yet translated, do it now
1418 //:abv 20.05.02: see comment in TransferShape(): added "! iasdr ||"
1419 Handle(Transfer_Binder) resprod = TransientResult(sdr); //KA - OCC7141(skl 10.11.2004)
1420 if ( ! iasdr || resbind.IsNull() ) {
1421 resbind = TransferShape(mapper, sdr, FP, shapeGroup, isManifold);
1422 Handle(Transfer_Binder) oldbind = FP->Find ( mapper );
1423 if ( ! oldbind.IsNull() && !resbind.IsNull()) resbind->AddResult ( oldbind );
1424 FP->Bind (mapper,resbind);
1425 resprod=resbind; //KA - OCC7141(skl 10.11.2004)
1426 }
1427
1428 // A new resbind may have been produced
1429// DeclareAndCast(Transfer_SimpleBinderOfTransient,restrans,resbind);
1430// if (restrans.IsNull()) return resbind;
1431// FP->GetTypedTransient (resbind,STANDARD_TYPE(StepShape_ShapeRepresentation),resultat);
1432// sdr->SetUsedRepresentation(resultat); // to be used by MakeItem
1433
1434 // make location for assembly placement
1435 GeomToStep_MakeAxis2Placement3d mkax (aLoc);
1436 Handle(StepGeom_Axis2Placement3d) AxLoc = mkax.Value();
1437 AX1 = AxLoc;
1438
1439 // create assembly structures (CDSR, NAUO etc.)
1440 STEPConstruct_Assembly mkitem;
1441 mkitem.Init (sdr,SDR0,myContext.GetDefaultAxis(),AxLoc);
1442 mkitem.MakeRelationship ();
1443 Handle(TColStd_HSequenceOfTransient) roots = myContext.GetRootsForAssemblyLink ( mkitem );
1444
1445 // add roots corresponding to assembly and product structures to binder
1446 //Handle(Transfer_Binder) resprod = resbind; //KA - OCC7141(skl 10.11.2004)
1447 //KA: we need only the current subshape in resprod, since the binder is copied
1448 // in Transfershape which calls Transfersubshape [ OCC7141(skl 10.11.2004) ]
1449 if ( ! iasdr ) {
1450 resprod->AddResult ( TransientResult ( SDRTool.SDRValue() ) );
1451 resbind->AddResult ( TransientResult ( SDRTool.SDRValue() ) ); //KA - OCC7141(skl 10.11.2004)
1452 roots->Append ( myContext.GetRootsForPart ( SDRTool ) );
1453 }
1454 for ( Standard_Integer i=1; i <= roots->Length(); i++ ) {
1455 resprod->AddResult ( TransientResult ( roots->Value(i) ) );
1456 resbind->AddResult ( TransientResult ( roots->Value(i) ) ); //KA - OCC7141(skl 10.11.2004)
1457 }
1458 myContext.NextIndex();
1459
1460 //FP->Bind (mapper,resprod); //KA - OCC7141(skl 10.11.2004)
1461
1462 // abv 16.10.00: bind CDSR (et al) to located shape in order to be able to track instances
1463 if ( mapper != start ) {
1464 Handle(Transfer_Binder) bnd = FP->Find ( start );
1465 for ( Standard_Integer j=1; j <= roots->Length(); j++ )
1466 if ( bnd.IsNull() ) bnd = TransientResult ( roots->Value(j) );
1467 else bnd->AddResult ( TransientResult ( roots->Value(j) ) );
1468 FP->Bind ( start, bnd );
1469 }
1470
1471 return resprod;
1472}