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