1 // Created on: 2001-11-26
2 // Created by: Sergey ZARITCHNY <szy@nnov.matra-dtv.fr>
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 #include <QANewBRepNaming_Gluing.ixx>
23 #include <BRep_Builder.hxx>
24 #include <TDF_Label.hxx>
25 #include <TDF_TagSource.hxx>
26 #include <TNaming_Builder.hxx>
27 #include <TNaming_NamedShape.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopoDS_Iterator.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <TDF_ChildIDIterator.hxx>
32 #include <TNaming_Selector.hxx>
33 #include <TNaming_Iterator.hxx>
34 #include <TNaming_Tool.hxx>
35 #include <TDF_AttributeMap.hxx>
36 #include <TDF_MapIteratorOfAttributeMap.hxx>
37 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39 #include <TopoDS_Edge.hxx>
41 #include <Precision.hxx>
42 #include <TDF_MapIteratorOfLabelMap.hxx>
43 #include <TDF_Tool.hxx>
44 #include <TopoDS_Vertex.hxx>
45 #include <BRep_Tool.hxx>
48 #include <TColStd_MapOfInteger.hxx>
49 #include <TDataStd_IntegerArray.hxx>
51 #include <QANewModTopOpe_Glue.hxx>
54 #include <TDataStd_Name.hxx>
57 #define SOURCES_SUBLABEL 1
59 //=======================================================================
60 //function : QANewBRepNaming_Gluing
62 //=======================================================================
64 QANewBRepNaming_Gluing::QANewBRepNaming_Gluing() {}
66 //=======================================================================
67 //function : QANewBRepNaming_Gluing
69 //=======================================================================
71 QANewBRepNaming_Gluing::QANewBRepNaming_Gluing(const TDF_Label& ResultLabel):QANewBRepNaming_TopNaming(ResultLabel) {}
73 //=======================================================================
76 //=======================================================================
78 void QANewBRepNaming_Gluing::Init(const TDF_Label& ResultLabel) {
79 if(ResultLabel.IsNull())
80 Standard_NullObject::Raise("QANewBRepNaming_Gluing::Init The Result label is Null ...");
81 myResultLabel = ResultLabel;
84 //=======================================================================
87 //=======================================================================
89 void QANewBRepNaming_Gluing::Load(QANewModTopOpe_Glue& theMkGluing) {
90 TopoDS_Shape aResShape = theMkGluing.Shape();
91 const TopoDS_Shape& anObjShape = theMkGluing.Shape1();
93 if (aResShape.IsNull()) {
95 cout<<"QANewBRepNaming_Gluing::Load(): The result of the Gluing operation is null"<<endl;
99 // If the shapes are the same - select the result and exit:
100 if (IsResultChanged(theMkGluing)) {
102 cout<<"QANewBRepNaming_Gluing::Load(): The object and the result of the operation are the same"<<endl;
104 if (aResShape.ShapeType() == TopAbs_COMPOUND) {
105 Standard_Integer aNbSubResults = 0;
106 TopoDS_Iterator anItr(theMkGluing.Shape());
107 for (; anItr.More(); anItr.Next()) aNbSubResults++;
108 if (aNbSubResults == 1) {
109 anItr.Initialize(aResShape);
110 if (anItr.More()) aResShape = anItr.Value();
113 TNaming_Builder aBuilder(ResultLabel());
114 aBuilder.Select(aResShape, anObjShape);
117 // Naming of the result:
118 // cout<<"********** RecomputeUnique"<<endl;
119 RecomputeUnique(theMkGluing);
120 TopTools_DataMapOfShapeInteger aSources;
122 // cout<<"********** LoadSourceShapes"<<endl;
123 LoadSourceShapes(aSources);
124 //mpv (there is must be shared elements anyway) if(theMkGluing.HasGenerated())
125 // cout<<"********** LoadUniqueShapes"<<endl;
126 LoadUniqueShapes(theMkGluing,aSources);
127 LoadContent(theMkGluing);
128 if(theMkGluing.HasModified()) {
129 LoadModifiedShapes(theMkGluing);
131 LoadResult(theMkGluing);
134 //=======================================================================
135 //function : ShapeType
137 //=======================================================================
139 TopAbs_ShapeEnum QANewBRepNaming_Gluing::ShapeType(const TopoDS_Shape& theShape) const {
140 TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
141 if (aShapeType == TopAbs_COMPOUND || aShapeType == TopAbs_COMPSOLID) {
142 TopoDS_Iterator itr(theShape);
143 if (itr.More()) aShapeType = itr.Value().ShapeType();
148 //=======================================================================
149 //function : GetShape
151 //=======================================================================
153 TopoDS_Shape QANewBRepNaming_Gluing::GetShape(const TopoDS_Shape& theShape) const {
154 if (theShape.ShapeType() == TopAbs_COMPOUND || theShape.ShapeType() == TopAbs_COMPSOLID) {
155 TopoDS_Iterator itr(theShape);
156 if (itr.More()) return itr.Value();
161 //=======================================================================
162 //function : LoadResult
164 //=======================================================================
166 void QANewBRepNaming_Gluing::LoadResult(QANewModTopOpe_Glue& theMkGluing) const {
167 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
168 if (Tagger.IsNull()) return;
170 TNaming_Builder aBuilder (ResultLabel());
171 TopoDS_Shape aResult = theMkGluing.Shape();
172 if (aResult.ShapeType() == TopAbs_COMPOUND) {
173 Standard_Integer aNbSubResults = 0;
174 TopoDS_Iterator anItr(aResult);
175 for (; anItr.More(); anItr.Next()) aNbSubResults++;
176 if (aNbSubResults == 1) {
177 anItr.Initialize(aResult);
178 if (anItr.More()) aResult = anItr.Value();
181 if (theMkGluing.Shape1().IsNull()) aBuilder.Generated(aResult);
183 aBuilder.Generated(theMkGluing.Shape1(), aResult); // mpv:?
188 //=======================================================================
189 //function : IsResultChanged
191 //=======================================================================
193 Standard_Boolean QANewBRepNaming_Gluing::IsResultChanged(QANewModTopOpe_Glue& theMkGluing) const {
194 TopoDS_Shape aResShape = theMkGluing.Shape();
195 if (theMkGluing.Shape().ShapeType() == TopAbs_COMPOUND) {
196 Standard_Integer aNbSubResults = 0;
197 TopoDS_Iterator anItr(theMkGluing.Shape());
198 for (; anItr.More(); anItr.Next()) aNbSubResults++;
199 if (aNbSubResults == 1) {
200 anItr.Initialize(theMkGluing.Shape());
201 if (anItr.More()) aResShape = anItr.Value();
204 return theMkGluing.Shape1().IsSame(aResShape);
207 //=======================================================================
208 //function : LoadModifiedShapes
210 //=======================================================================
212 void QANewBRepNaming_Gluing::LoadModifiedShapes(QANewModTopOpe_Glue& theMkGluing) const {
213 const Standard_Integer aNumTypes = 1;
214 const TopAbs_ShapeEnum aTypes[] = {TopAbs_FACE/*,TopAbs_EDGE,TopAbs_VERTEX*/};
216 const char aNames[][20] = {"ModifiedFaces"/*,"ModifiedEdges","ModifiedVertexes"*/};
218 Standard_Integer aShapeNum;
220 TDF_Label aLabel = ResultLabel().FindChild(1,Standard_True);
221 Handle(TNaming_NamedShape) aNS;
222 while(aLabel.FindAttribute(TNaming_NamedShape::GetID(),aNS)) {
223 if (aNS->Evolution() == TNaming_MODIFY) break;
224 aLabel = aLabel.Father().FindChild(aLabel.Tag()+1,Standard_True);
226 for(Standard_Integer a=0;a<aNumTypes;a++) { // argument-shapes types cycle
228 TDataStd_Name::Set(aLabel,TCollection_ExtendedString(Standard_CString(aNames[a])));
230 TNaming_Builder aBuilder(aLabel);
231 // functionality from Loader
232 TopExp_Explorer ShapeExplorer;
233 for(aShapeNum=0;aShapeNum<2;aShapeNum++) { // argument-shapes cycle
234 if (aShapeNum==0) ShapeExplorer.Init(theMkGluing.Shape1(), aTypes[a]);
235 else ShapeExplorer.Init(theMkGluing.Shape2(), aTypes[a]);
236 TopTools_MapOfShape View;
237 for (; ShapeExplorer.More(); ShapeExplorer.Next ()) { // argument-shapes subshapes cycle
238 const TopoDS_Shape& Root = ShapeExplorer.Current ();
239 if (!View.Add(Root)) continue;
240 const TopTools_ListOfShape& Shapes = theMkGluing.Modified(Root);
241 TopTools_ListIteratorOfListOfShape ShapesIterator (Shapes);
242 for (;ShapesIterator.More (); ShapesIterator.Next ()) { // argument-shapes subshapes parents cycle
243 const TopoDS_Shape& newShape = ShapesIterator.Value ();
244 if (!Root.IsSame (newShape) && !myUnique.Contains(newShape)) { // modifyed compound can't contains unique
245 aBuilder.Modify(Root,newShape);
250 if (a+1<aNumTypes) aLabel = aLabel.Father().FindChild(aLabel.Tag()+1,Standard_True);
254 //=======================================================================
255 //function : SetContext
257 //=======================================================================
259 void QANewBRepNaming_Gluing::SetContext(const TopoDS_Shape& theObject,
260 const TopoDS_Shape& theTool) {
261 TopoDS_Compound aCompound;
263 aB.MakeCompound(aCompound);
264 aB.Add(aCompound,theObject);
265 aB.Add(aCompound,theTool);
266 myContext = aCompound;
269 //=======================================================================
272 //=======================================================================
274 void QANewBRepNaming_Gluing::SetLog(const TDF_LabelMap& theLog) {
275 myLog.Assign(theLog);
278 //=======================================================================
279 //function : AddToTheUnique
281 //=======================================================================
282 void QANewBRepNaming_Gluing::AddToTheUnique(const TopoDS_Shape& theUnique, const TopoDS_Shape& theIdentifier) {
283 if (!myUnique.Contains(theUnique)) {
284 TopTools_ListOfShape* aNewList = new TopTools_ListOfShape;
285 aNewList->Append(theIdentifier);
286 myUnique.Add(theUnique, *aNewList);
288 myUnique.ChangeFromKey(theUnique).Append(theIdentifier);
292 //=======================================================================
293 //function : RecomputeUnique
295 //=======================================================================
296 void QANewBRepNaming_Gluing::RecomputeUnique(QANewModTopOpe_Glue& theMkGluing) {
297 const Standard_Integer aNumTypes = 3;
298 const TopAbs_ShapeEnum aTypes[] = {TopAbs_FACE,TopAbs_EDGE,TopAbs_VERTEX};
300 // special case: edges may be divided, these edges (new and modified)
301 // we try to sort in the algorithm returned lists order
303 Standard_Integer aNext;
304 TopExp_Explorer anExp(myContext, TopAbs_EDGE);
305 TopTools_ListIteratorOfListOfShape anEdgesIterator;
306 for(;anExp.More();anExp.Next()) {
307 for(aNext=0;aNext<2;aNext++) {
308 TopoDS_Edge aFullEdge = TopoDS::Edge(anExp.Current());
309 if (aNext == 0) anEdgesIterator.Initialize(theMkGluing.Generated(aFullEdge));
310 else anEdgesIterator.Initialize(theMkGluing.Modified(aFullEdge));
311 for (;anEdgesIterator.More();anEdgesIterator.Next())
312 if (anEdgesIterator.Value().ShapeType() == TopAbs_EDGE) {
313 TopoDS_Edge aDivEdge = TopoDS::Edge(anEdgesIterator.Value());
314 if (!TopExp::FirstVertex(aDivEdge).IsNull()) { // divided edge must have at least one vertex
315 if (TopExp::FirstVertex(aFullEdge).IsNull()) AddToTheUnique(aDivEdge,aFullEdge);
316 else if (!TopExp::LastVertex(aDivEdge).IsNull())//if full edge have at least one vertex, subedges must have two
317 if (TopExp::LastVertex(aFullEdge).IsNull()) {
318 if (BRep_Tool::Pnt(TopExp::FirstVertex(aFullEdge)).
319 IsEqual(BRep_Tool::Pnt(TopExp::FirstVertex(aDivEdge)),Precision::Confusion()))
320 AddToTheUnique(aDivEdge,aFullEdge);
321 else if (BRep_Tool::Pnt(TopExp::FirstVertex(aFullEdge)).
322 IsEqual(BRep_Tool::Pnt(TopExp::LastVertex(aDivEdge)),Precision::Confusion()))
323 AddToTheUnique(aDivEdge,aFullEdge);
325 Standard_Integer aCounter = 0;
326 if (BRep_Tool::Pnt(TopExp::FirstVertex(aFullEdge)).
327 IsEqual(BRep_Tool::Pnt(TopExp::FirstVertex(aDivEdge)),Precision::Confusion()) ||
328 BRep_Tool::Pnt(TopExp::FirstVertex(aFullEdge)).
329 IsEqual(BRep_Tool::Pnt(TopExp::LastVertex(aDivEdge)),Precision::Confusion())) aCounter++;
330 if (BRep_Tool::Pnt(TopExp::LastVertex(aFullEdge)).
331 IsEqual(BRep_Tool::Pnt(TopExp::FirstVertex(aDivEdge)),Precision::Confusion()) ||
332 BRep_Tool::Pnt(TopExp::LastVertex(aFullEdge)).
333 IsEqual(BRep_Tool::Pnt(TopExp::LastVertex(aDivEdge)),Precision::Confusion())) aCounter++;
334 if (aCounter!=2) AddToTheUnique(aDivEdge,aFullEdge);
342 Standard_Integer aDividedIndex = myUnique.Extent();;
343 // accumulate all shapes, modifyed from shape1
345 for(Standard_Integer a=0;a<aNumTypes;a++) {
346 TopExp_Explorer ShapeExplorer1;
347 if (aNext==2) ShapeExplorer1.Init(theMkGluing.Shape1(), aTypes[a]);
348 else ShapeExplorer1.Init(theMkGluing.Shape2(), aTypes[a]);
349 for (; ShapeExplorer1.More(); ShapeExplorer1.Next ()) {
350 TopTools_ListIteratorOfListOfShape ShapesIterator1(theMkGluing.Generated(ShapeExplorer1.Current()));
351 for (;ShapesIterator1.More (); ShapesIterator1.Next ()) {
352 if (myUnique.Contains(ShapesIterator1.Value()))
353 if (myUnique.FindIndex(ShapesIterator1.Value()) <= aDividedIndex) continue;
354 AddToTheUnique(ShapesIterator1.Value(),ShapeExplorer1.Current());
362 cout<<"QANewBRepNaming_Gluing::RecomputeUnique found "<<myUnique.Extent()<<" shapes"<<endl;
366 //=======================================================================
367 //function : LoadSourceShapes
369 //=======================================================================
370 void QANewBRepNaming_Gluing::LoadSourceShapes(TopTools_DataMapOfShapeInteger& theSources) const {
372 cout<<"********** QANewBRepNaming_Gluing::LoadSourceShapes the valid map:"<<endl;
373 TDF_MapIteratorOfLabelMap anIter(myLog);
374 for(;anIter.More();anIter.Next()) {
375 TCollection_AsciiString entry;
376 TDF_Tool::Entry(anIter.Key(), entry);
382 TDF_Label aLabel = ResultLabel().FindChild(SOURCES_SUBLABEL);
383 Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(aLabel);
384 if (Tagger.IsNull()) return;
387 // get all source shapes (in the given order)
388 TopTools_MapOfShape aShapes;
389 TopTools_ListOfShape aSortedShapes;
390 Standard_Integer anIndex;
391 for(anIndex=1;anIndex<=myUnique.Extent();anIndex++) {
392 TopTools_ListIteratorOfListOfShape anIter2(myUnique.FindFromIndex(anIndex));
393 for(;anIter2.More();anIter2.Next()) {
394 if (!aShapes.Contains(anIter2.Value())) {
395 aShapes.Add(anIter2.Value());
396 aSortedShapes.Append(anIter2.Value());
400 // put all source shapes to the sources label sublabels
401 TopTools_ListIteratorOfListOfShape aSortedIterator(aSortedShapes);
402 for(aLabel = aLabel.NewChild();aShapes.Extent();aLabel = aLabel.Father().NewChild()) {
403 Handle(TNaming_NamedShape) aNS;
404 if (aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
405 // old shape resolving
407 aValid.Assign(myLog);
408 TNaming_Selector aSel(aLabel);
410 TopoDS_Shape aShape = aSel.NamedShape()->Get();
411 if (aShapes.Contains(aShape)) {
412 theSources.Bind(aShape,aLabel.Tag());
413 aShapes.Remove(aShape);
417 for(;aSortedIterator.More();aSortedIterator.Next()) {
418 TopoDS_Shape aShape = aSortedIterator.Value();;
419 if (aShapes.Contains(aShape)) {
420 theSources.Bind(aShape,aLabel.Tag());
421 aShapes.Remove(aShape);
422 TNaming_Selector aSelector(aLabel);
423 if (!aSelector.Select(aShape,myContext)) {
425 cout<<"Can't do naming"<<endl;
436 //=======================================================================
437 //function : LoadUniqueShapes
439 //=======================================================================
440 void QANewBRepNaming_Gluing::LoadUniqueShapes(QANewModTopOpe_Glue& /*theMkGluing*/,
441 const TopTools_DataMapOfShapeInteger& theSources)
443 Standard_Integer anIndex=1;
444 TColStd_MapOfInteger alreadyUsed;
445 while(alreadyUsed.Extent() != myUnique.Extent()) { // result sublabels cycle
446 TDF_Label aLabel = ResultLabel().NewChild();
447 Handle(TNaming_NamedShape) aNS;
448 if (aLabel.FindAttribute(TNaming_NamedShape::GetID(),aNS)) {
449 if (aNS->Evolution() == TNaming_MODIFY) continue;
450 Handle(TDataStd_IntegerArray) anArray;
451 if (aLabel.FindAttribute(TDataStd_IntegerArray::GetID(),anArray)) { // old unique with dependencies
453 for(a = anIndex;a<=myUnique.Extent();a++) {
454 if (alreadyUsed.Contains(a)) continue;
455 if (myUnique.FindFromIndex(a).Extent()!=anArray->Upper()) continue;
456 // cout<<"a="<<a<<endl;
457 TopTools_ListIteratorOfListOfShape anIter2(myUnique.FindFromIndex(a));
458 Standard_Boolean aEq = Standard_True;
459 for(;anIter2.More() && aEq;anIter2.Next()) {
460 Standard_Integer aValue = theSources.Find(anIter2.Value());
462 for(a1=anArray->Upper();a1>=1;a1--) if (anArray->Value(a1) == aValue) break;
463 if (a1 == 0) aEq = Standard_False;
465 // cout<<"eq="<<aEq<<endl;
467 TNaming_Builder aBuilder(aLabel);
468 aBuilder.Generated(myUnique.FindKey(a));
477 while(alreadyUsed.Contains(anIndex)) anIndex++;
478 // cout<<"anIndex = "<<anIndex<<endl;
479 Handle(TDataStd_IntegerArray) anArray=TDataStd_IntegerArray::Set(aLabel,1,myUnique.FindFromIndex(anIndex).Extent());
480 TopTools_ListIteratorOfListOfShape anIter(myUnique.FindFromIndex(anIndex));
482 for(a=1;anIter.More();anIter.Next(),a++) {
483 anArray->SetValue(a,theSources.Find(anIter.Value()));
485 TNaming_Builder aBuilder(aLabel);
486 aBuilder.Generated(myUnique.FindKey(anIndex));
487 alreadyUsed.Add(anIndex);
492 //=======================================================================
495 //=======================================================================
496 TDF_Label QANewBRepNaming_Gluing::Content() const {
498 const TDF_Label& ContentLabel = ResultLabel().NewChild();
499 TDataStd_Name::Set(ContentLabel, "Content");
502 return ResultLabel().NewChild();
506 //=======================================================================
507 //function : LoadUniqueShapes
509 //=======================================================================
510 void QANewBRepNaming_Gluing::LoadContent(QANewModTopOpe_Glue& MS) const {
511 if (MS.Shape().ShapeType() == TopAbs_COMPSOLID || MS.Shape().ShapeType() == TopAbs_COMPOUND) {
512 TopoDS_Iterator itr(MS.Shape());
513 Standard_Integer nbShapes = 0;
519 for (itr.Initialize(MS.Shape()); itr.More(); itr.Next()) {
520 TNaming_Builder bContent(Content());
521 bContent.Generated(itr.Value());