1a3eb1b4026555ed845473909e56c9223788ce58
[occt.git] / src / QANewModTopOpe / QANewModTopOpe_Glue_SDFaces.cxx
1 // File:        QANewModTopOpe_Glue_solid.cxx
2 // Created:     Sat May  5 09:55:59 2001
3 // Author:      Sergey KHROMOV <skv@nnov.matra-dtv.fr>
4 // Copyright:    SAMTECH S.A. 2001
5
6 const static char sccsid[] = "@(#) QANewModTopOpe_Glue_SDFaces.cxx 4.2-3, 01/07/04@(#)";
7
8 // Lastly modified by :
9 // +---------------------------------------------------------------------------+
10 // !       pat ! fix for 4086                            !  01/07/04!    4.2-3!
11 // !       skv ! Adaptation to OCC version 5.0           ! 6-05-2003! 3.0-00-2!
12 // +---------------------------------------------------------------------------+
13
14
15 #include <QANewModTopOpe_Glue.ixx>
16 #include <TopExp_Explorer.hxx>
17 #include <TopoDS.hxx>
18 #include <TopTools_ListIteratorOfListOfShape.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopoDS_Compound.hxx>
21 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
22 #include <TopTools_MapOfShape.hxx>
23 #include <TopTools_MapIteratorOfMapOfShape.hxx>
24 #include <TopExp.hxx>
25 #include <QANewModTopOpe_Tools.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <Geom_TrimmedCurve.hxx>
29 #include <GeomProjLib.hxx>
30 #include <Precision.hxx>
31 #include <BRepAdaptor_Surface.hxx>
32
33 static Standard_Boolean isAnalitic(const TopoDS_Shape &theShape)
34 {
35   if (theShape.ShapeType() != TopAbs_FACE)
36     return Standard_False;
37
38   TopoDS_Face          aFace = TopoDS::Face(theShape);
39   BRepAdaptor_Surface  aSurf(aFace);
40   Standard_Boolean     isAna = Standard_False;
41
42   switch (aSurf.GetType()) {
43   case GeomAbs_Plane :
44   case GeomAbs_Cylinder :
45   case GeomAbs_Cone :
46   case GeomAbs_Sphere :
47   case GeomAbs_Torus :
48     isAna = Standard_True;
49     break;
50   default:
51     isAna = Standard_False;
52   }
53
54   return isAna;
55 }
56
57 static void DoPCurveOnF(const TopoDS_Edge &theEdge, const TopoDS_Face &theFace)
58 {
59   BRep_Builder              aBuilder;
60   TopLoc_Location           aCLoc;
61   TopLoc_Location           aSLoc;
62   Standard_Real             aF;
63   Standard_Real             aL;
64   Handle(Geom_Curve)        aCurve   = BRep_Tool::Curve(theEdge, aCLoc, aF, aL);
65   Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, aF, aL);
66   Handle(Geom_Surface)      aSurface = BRep_Tool::Surface(theFace, aSLoc);
67   TopLoc_Location           aCTLoc   = aSLoc.Inverted().Multiplied(aCLoc);
68
69   aTrCurve->Transform(aCTLoc.Transformation());
70   
71   Handle(Geom2d_Curve) aCurve2d = GeomProjLib::Curve2d (aTrCurve, aSurface);
72
73   aBuilder.UpdateEdge(theEdge, aCurve2d, aSurface,
74                       aSLoc, Precision::Confusion());
75 }
76
77 static TopoDS_Face GetAdjacentFace
78                    (const TopoDS_Shape                              &theEdge,
79                     const TopoDS_Shape                              &theFace,
80                     const TopTools_IndexedDataMapOfShapeListOfShape &theAncMap)
81 {
82   TopoDS_Face aFace;
83
84   if (theAncMap.Contains(theEdge)) {
85     const TopTools_ListOfShape         &aLOfFaces =
86                                               theAncMap.FindFromKey(theEdge);
87     TopTools_ListIteratorOfListOfShape  anIter(aLOfFaces);
88
89     for (; anIter.More(); anIter.Next()) {
90       const TopoDS_Shape &aLocalFace = anIter.Value();
91
92       if (!theFace.IsSame(aLocalFace)) {
93         aFace = TopoDS::Face(aLocalFace);
94         break;
95       }
96     }
97   }
98
99   return aFace;
100 }
101
102 //=======================================================================
103 //function : SubstitudeSDFaces
104 //purpose  : 
105 //=======================================================================
106
107 Standard_Boolean QANewModTopOpe_Glue::SubstitudeSDFaces
108           (const TopoDS_Shape                       &theFirstSDFace,
109            const TopoDS_Shape                       &theSecondSDFace,
110                  TopoDS_Shape                       &theNewSolid1,
111                  TopoDS_Shape                       &theNewSolid2,
112                  TopTools_DataMapOfShapeListOfShape &theMapOfChangedFaces) 
113 {
114 // If the first face is already splited, we use its splits
115 // to recursively call this function.
116   if (theMapOfChangedFaces.IsBound(theFirstSDFace)) {
117     const TopTools_ListOfShape &aLocalList = 
118                                 theMapOfChangedFaces(theFirstSDFace);
119     TopTools_ListIteratorOfListOfShape anIter(aLocalList);
120
121     for (;anIter.More(); anIter.Next()) {
122       const TopoDS_Shape &aNewShape = anIter.Value();
123       if (!SubstitudeSDFaces(aNewShape,    theSecondSDFace,
124                              theNewSolid1, theNewSolid2,
125                              theMapOfChangedFaces))
126         return Standard_False;
127     }
128     return Standard_True;
129   }
130
131 // If the second face is already splited, we use its splits
132 // to recursively call this function.
133   if (theMapOfChangedFaces.IsBound(theSecondSDFace)) {
134     const TopTools_ListOfShape &aLocalList = 
135                                 theMapOfChangedFaces(theSecondSDFace);
136     TopTools_ListIteratorOfListOfShape anIter(aLocalList);
137
138     for (;anIter.More(); anIter.Next()) {
139       const TopoDS_Shape &aNewShape = anIter.Value();
140       if (!SubstitudeSDFaces(theFirstSDFace,    aNewShape,
141                              theNewSolid1, theNewSolid2,
142                              theMapOfChangedFaces))
143         return Standard_False;
144     }
145     return Standard_True;
146   }
147
148
149 // If neither the first face nor the second one were
150 //  splited before, we begin calculation:
151   TopTools_IndexedDataMapOfShapeListOfShape aHistory;
152   Standard_Boolean                          isCommonFound;
153
154   if (!QANewModTopOpe_Tools::BoolOpe(theFirstSDFace.Oriented(TopAbs_FORWARD),
155                                 theSecondSDFace.Oriented(TopAbs_FORWARD),
156                                 isCommonFound, aHistory))
157     return Standard_False;
158
159   if (!isCommonFound)
160     return Standard_True;
161
162   TopTools_IndexedDataMapOfShapeListOfShape anAncMap1;
163   TopTools_IndexedDataMapOfShapeListOfShape anAncMap2;
164
165   TopExp::MapShapesAndAncestors(theNewSolid1, TopAbs_EDGE,
166                                 TopAbs_FACE, anAncMap1);
167   TopExp::MapShapesAndAncestors(theNewSolid2, TopAbs_EDGE,
168                                 TopAbs_FACE, anAncMap2);
169
170 // Creation of a compound of old solids.
171 // The substitution operation will be built with this
172 // compound.
173   BRep_Builder    aBuilder;
174   TopoDS_Compound aCompound;
175
176   aBuilder.MakeCompound(aCompound);
177   aBuilder.Add(aCompound, theNewSolid1);
178   aBuilder.Add(aCompound, theNewSolid2);
179
180 // Substitution of updated sub-shapes of the first solid.
181   BRepTools_Substitution aSubstTool;
182   Standard_Integer       aNbModifShape = aHistory.Extent();
183   Standard_Integer       i;
184
185   for (i = 1; i <= aNbModifShape; i++) {
186     TopTools_ListOfShape                aModifShapes;
187     const TopoDS_Shape                 &anAncestor = aHistory.FindKey(i);
188     TopTools_ListIteratorOfListOfShape  anIter(aHistory.FindFromIndex(i));
189
190     if (anAncestor.IsSame(theSecondSDFace)) {
191       for (; anIter.More(); anIter.Next())
192         aModifShapes.Append(anIter.Value());
193     } else {
194       for (; anIter.More(); anIter.Next())
195         aModifShapes.Append(anIter.Value().Oriented(TopAbs_FORWARD));
196     }
197
198     if (anAncestor.ShapeType() == TopAbs_EDGE) {
199 // Check if the edges from common contain pcurves on both shapes.
200 // If they do not, create them.
201       TopoDS_Edge anAncEdge  = TopoDS::Edge(anAncestor);
202
203       if (anAncMap1.Contains(anAncestor)) {
204         TopoDS_Face   aFace = GetAdjacentFace(anAncestor, theFirstSDFace,
205                                               anAncMap1);
206         if(!aFace.IsNull()) {//added to fix 4086
207           Standard_Real aFirst;
208           Standard_Real aLast;
209           
210           anIter.Initialize(aHistory.FindFromIndex(i));
211           for (; anIter.More(); anIter.Next()) {
212             TopoDS_Edge          aSplit  = TopoDS::Edge(anIter.Value());
213             Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
214               (aSplit, aFace, aFirst, aLast);
215             
216             if (aPCurve.IsNull())
217               DoPCurveOnF(aSplit, aFace);
218           }
219         }
220       }
221       
222       if (anAncMap2.Contains(anAncestor)) {
223         TopoDS_Face   aFace = GetAdjacentFace(anAncestor, theSecondSDFace,
224                                               anAncMap2);
225         if(!aFace.IsNull()) {//added to fix 4086
226           Standard_Real aFirst;
227           Standard_Real aLast;
228           
229           anIter.Initialize(aHistory.FindFromIndex(i));
230           for (; anIter.More(); anIter.Next()) {
231             TopoDS_Edge          aSplit  = TopoDS::Edge(anIter.Value());
232             Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
233               (aSplit, aFace, aFirst, aLast);
234             
235             if (aPCurve.IsNull())
236               DoPCurveOnF(aSplit, aFace);
237           }
238         }
239       }
240     }
241     
242 //--------------------------------------------------------------
243     if (!myMapModif.IsBound(anAncestor))
244       myMapModif.Bind(anAncestor, aModifShapes);
245 //--------------------------------------------------------------
246
247     aSubstTool.Substitute(anAncestor, aModifShapes);
248   }
249
250   aSubstTool.Build(aCompound);
251   
252 // Update the map theMapOfChangedFaces and 
253 // obtain a new solid from the first one.
254   if (aSubstTool.IsCopied(theNewSolid1)) {
255     // Add changed faces of the first solid to theMapOfChangedFaces:
256     TopExp_Explorer  anExp(theNewSolid1, TopAbs_FACE);
257     for (; anExp.More(); anExp.Next()) {
258       // For each face from solid
259       const TopoDS_Shape &aFace = anExp.Current();
260
261       if (aSubstTool.IsCopied(aFace)) {
262         const TopTools_ListOfShape &aList = aSubstTool.Copy(aFace);
263
264         TopTools_ListOfShape aNewList;
265         if (!theMapOfChangedFaces.IsBound(aFace))
266           theMapOfChangedFaces.Bind(aFace, aNewList);
267         
268         TopTools_ListIteratorOfListOfShape anIter(aList);
269         for (; anIter.More(); anIter.Next()) {
270           TopoDS_Shape aLocalFace = anIter.Value();
271
272           if (aSubstTool.IsCopied(aLocalFace))
273             aLocalFace = aSubstTool.Copy(aLocalFace).First();
274
275           theMapOfChangedFaces(aFace).Append(aLocalFace);
276         }
277       }
278     }
279     // Obtain a new solid.
280     theNewSolid1 = aSubstTool.Copy(theNewSolid1).First();
281   }
282
283 // Update the map theMapOfChangedFaces and 
284 // obtain a new solid from the second one.
285   if (aSubstTool.IsCopied(theNewSolid2)) {
286     // Add changed faces of the second solid to theMapOfChangedFaces:
287     TopExp_Explorer  anExp(theNewSolid2, TopAbs_FACE);
288     for (; anExp.More(); anExp.Next()) {
289       // For each face from solid
290       const TopoDS_Shape &aFace = anExp.Current();
291
292       if (aSubstTool.IsCopied(aFace)) {
293         const TopTools_ListOfShape &aList = aSubstTool.Copy(aFace);
294
295         TopTools_ListOfShape aNewList;
296         if (!theMapOfChangedFaces.IsBound(aFace))
297           theMapOfChangedFaces.Bind(aFace, aNewList);
298         
299         TopTools_ListIteratorOfListOfShape anIter(aList);
300         for (; anIter.More(); anIter.Next()) {
301           TopoDS_Shape aLocalFace = anIter.Value();
302
303           if (aSubstTool.IsCopied(aLocalFace))
304             aLocalFace = aSubstTool.Copy(aLocalFace).First();
305
306           theMapOfChangedFaces(aFace).Append(aLocalFace);
307         }
308       }
309     }
310     // Obtain a new solid.
311     theNewSolid2 = aSubstTool.Copy(theNewSolid2).First();
312   }
313
314   return Standard_True;
315 }
316
317 //=======================================================================
318 //function : PerformSolidSolid
319 //purpose  : 
320 //=======================================================================
321
322 void
323 QANewModTopOpe_Glue::PerformSDFaces()
324 {
325   TopExp_Explorer anExp;
326   TopoDS_Shape aS1, aS2;
327   Standard_Boolean aWire1 = Standard_False, aWire2 = Standard_False; 
328   anExp.Init(myS1, TopAbs_WIRE, TopAbs_FACE);
329   if(anExp.More()) {
330     aS1 = myS1;
331     aWire1 = Standard_True;
332   }
333   else {
334     anExp.Init(myS1, TopAbs_EDGE, TopAbs_WIRE);
335     if(anExp.More()) {
336       aS1 = myS1;
337       aWire1 = Standard_True;
338     }
339   }
340    
341   anExp.Init(myS2, TopAbs_WIRE, TopAbs_FACE);
342   if(anExp.More()) {
343     aS2 = myS2;
344     aWire2 = Standard_True;
345   }
346   else {
347     anExp.Init(myS2, TopAbs_EDGE, TopAbs_WIRE);
348     if(anExp.More()) {
349       aS2 = myS2;
350       aWire2 = Standard_True;
351     }
352   }
353  
354   if(aWire1) {
355     BRep_Builder aBld;
356     myS1.Nullify();
357     aBld.MakeCompound(TopoDS::Compound(myS1));
358     anExp.Init(aS1, TopAbs_COMPSOLID);
359     for(; anExp.More(); anExp.Next()) {
360       aBld.Add(myS1, anExp.Current());
361     }
362     
363     anExp.Init(aS1, TopAbs_SOLID, TopAbs_COMPSOLID);
364     for(; anExp.More(); anExp.Next()) {
365       aBld.Add(myS1, anExp.Current());
366     }
367     
368     anExp.Init(aS1, TopAbs_SHELL, TopAbs_SOLID);
369     for(; anExp.More(); anExp.Next()) {
370       aBld.Add(myS1, anExp.Current());
371     }
372     
373     anExp.Init(aS1, TopAbs_FACE, TopAbs_SHELL);
374     for(; anExp.More(); anExp.Next()) {
375       aBld.Add(myS1, anExp.Current());
376     }
377     
378   }
379
380   if(aWire2) {
381     BRep_Builder aBld;
382     myS2.Nullify();
383     aBld.MakeCompound(TopoDS::Compound(myS2));
384     anExp.Init(aS2, TopAbs_COMPSOLID);
385     for(; anExp.More(); anExp.Next()) {
386       aBld.Add(myS2, anExp.Current());
387     }
388     
389     anExp.Init(aS2, TopAbs_SOLID, TopAbs_COMPSOLID);
390     for(; anExp.More(); anExp.Next()) {
391       aBld.Add(myS2, anExp.Current());
392     }
393     
394     anExp.Init(aS2, TopAbs_SHELL, TopAbs_SOLID);
395     for(; anExp.More(); anExp.Next()) {
396       aBld.Add(myS2, anExp.Current());
397     }
398     
399     anExp.Init(aS2, TopAbs_FACE, TopAbs_SHELL);
400     for(; anExp.More(); anExp.Next()) {
401       aBld.Add(myS2, anExp.Current());
402     }
403     
404   }
405
406   BRepAlgoAPI_BooleanOperation::Build();
407   if (!BuilderCanWork())
408     return;
409
410   if(aWire1) myS1 = aS1;
411   if(aWire2) myS2 = aS2;
412
413   myShape.Nullify();
414
415   TopoDS_Shape                         aNewShape1 = myS1;
416   TopoDS_Shape                         aNewShape2 = myS2;
417   TopTools_DataMapOfShapeListOfShape   theMapOfChangedFaces;
418
419   Standard_Boolean aHasSDF = Standard_False;
420   anExp.Init(myS1, TopAbs_FACE);
421   for (; anExp.More(); anExp.Next()) {
422     TopoDS_Shape aFirstFace = anExp.Current();
423
424     if (!isAnalitic(aFirstFace))
425       continue;
426
427     if (QANewModTopOpe_Tools::HasSameDomain(myDSFiller, aFirstFace)) {
428
429       if(!aHasSDF) aHasSDF = Standard_True;
430
431       TopTools_ListOfShape               aLOfSDFace;
432       TopTools_ListIteratorOfListOfShape anIter;
433
434       QANewModTopOpe_Tools::SameDomain(myDSFiller, aFirstFace, aLOfSDFace);
435       anIter.Initialize(aLOfSDFace);
436
437       for(; anIter.More(); anIter.Next()) {
438         TopoDS_Shape aSecondFace = anIter.Value();
439
440         if (!isAnalitic(aSecondFace))
441           continue;
442
443         if (!SubstitudeSDFaces(aFirstFace, aSecondFace,
444                                aNewShape1, aNewShape2,
445                                theMapOfChangedFaces))
446           return;
447       }
448     }
449   }
450
451   if(myS1.IsSame(aNewShape1) && myS2.IsSame(aNewShape2)) return;
452
453   if(aHasSDF) {
454     BRep_Builder aBuilder;
455
456 //    aBuilder.MakeCompSolid(TopoDS::CompSolid(myShape));
457     aBuilder.MakeCompound(TopoDS::Compound(myShape));
458
459     aBuilder.Add(myShape, aNewShape1);
460     aBuilder.Add(myShape, aNewShape2);
461
462     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anIter(theMapOfChangedFaces);
463     for(; anIter.More(); anIter.Next()) {
464       myMapModif.Bind(anIter.Key(), anIter.Value());
465     }
466
467     //--------------- creation myMapGener for common faces
468     
469     TopExp_Explorer anExp1, anExp2;
470     TopTools_MapOfShape aM;
471     anExp1.Init(aNewShape1, TopAbs_FACE);
472     for(; anExp1.More(); anExp1.Next()) {
473       const TopoDS_Shape& aF1 = anExp1.Current();
474       anExp2.Init(aNewShape2, TopAbs_FACE);
475       for(; anExp2.More(); anExp2.Next()) {
476         const TopoDS_Shape& aF2 = anExp2.Current();
477         if(aF1.IsSame(aF2)) {
478           aM.Add(aF1);
479         }
480       }
481     }
482
483     anIter.Initialize(myMapModif);
484     TopTools_ListIteratorOfListOfShape anI1;
485     TopTools_MapIteratorOfMapOfShape anI2;
486     for(; anIter.More(); anIter.Next()) {
487       const TopoDS_Shape& aS = anIter.Key();
488       if(aS.ShapeType() == TopAbs_FACE) {
489         anI1.Initialize(anIter.Value());
490         for(; anI1.More(); anI1.Next()) {
491           const TopoDS_Shape& aSS1 = anI1.Value();
492           anI2.Initialize(aM);
493           for(; anI2.More(); anI2.Next()) {
494             const TopoDS_Shape& aSS2 = anI2.Key();
495             if(aSS1.IsSame(aSS2)) {
496               if(!myMapGener.IsBound(aS)) {
497                 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aS, TopTools_ListOfShape());
498                 TopTools_ListOfShape aListOfShape1;
499                 myMapGener.Bind(aS, aListOfShape1);
500               }
501               myMapGener(aS).Append(aSS1);
502               myMapModif(aS).Remove(anI1);
503             }
504           }
505           if(!anI1.More()) break;
506         }
507       }
508       
509 //      if(anIter.Value().Extent() == 0) myMapModif.UnBind(aS);
510
511     }
512               
513     //--------------- creation myMapGener for common edges
514     
515     aM.Clear();
516     anExp1.Init(aNewShape1, TopAbs_EDGE);
517     for(; anExp1.More(); anExp1.Next()) {
518       const TopoDS_Shape& anE1 = anExp1.Current();
519       if(aM.Contains(anE1)) continue;
520       anExp2.Init(aNewShape2, TopAbs_EDGE);
521       for(; anExp2.More(); anExp2.Next()) {
522         const TopoDS_Shape& anE2 = anExp2.Current();
523         if(aM.Contains(anE2)) continue;
524         if(anE1.IsSame(anE2)) {
525           aM.Add(anE1);
526         }
527       }
528     }
529
530     anIter.Initialize(myMapModif);
531     TopTools_MapOfShape aComVerMap;
532     TopTools_MapOfShape aLocVerMap;
533
534     anExp1.Init(myS1, TopAbs_VERTEX);
535     for(; anExp1.More();  anExp1.Next()) aComVerMap.Add(anExp1.Current());
536     anExp1.Init(myS2, TopAbs_VERTEX);
537     for(; anExp1.More();  anExp1.Next()) aComVerMap.Add(anExp1.Current());
538
539     for(; anIter.More(); anIter.Next()) {
540       const TopoDS_Shape& aS = anIter.Key();
541       if(aS.ShapeType() == TopAbs_EDGE) {
542         aLocVerMap.Clear();
543         anI1.Initialize(anIter.Value());
544         for(; anI1.More(); anI1.Next()) {
545           const TopoDS_Shape& aSS1 = anI1.Value();
546           anI2.Initialize(aM);
547           for(; anI2.More(); anI2.Next()) {
548             const TopoDS_Shape& aSS2 = anI2.Key();
549             if(aSS1.IsSame(aSS2)) {
550               if(!aS.IsSame(aSS1)) {
551                 if(!myMapGener.IsBound(aS)) {
552                   // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aS, TopTools_ListOfShape());
553                   TopTools_ListOfShape aListOfShape2;
554                   myMapGener.Bind(aS, aListOfShape2);
555                 }
556                 myMapGener(aS).Append(aSS1);
557                 TopoDS_Vertex aV1, aV2;
558                 TopExp::Vertices(TopoDS::Edge(aSS1), aV1, aV2);
559                 if(!aComVerMap.Contains(aV1)) { 
560                   if(aLocVerMap.Add(aV1)) {
561                     myMapGener(aS).Append(aV1);
562                   }
563                 }
564                 if(!aComVerMap.Contains(aV2)) { 
565                   if(aLocVerMap.Add(aV2)) {
566                     myMapGener(aS).Append(aV2);
567                   }
568                 }
569                 myMapModif(aS).Remove(anI1);
570               }
571               else {
572                 myMapModif.UnBind(aS);
573               }
574             }
575           }
576           if(!anI1.More()) break;
577         }
578       }
579       
580 //      if(anIter.Value().Extent() == 0) myMapModif.UnBind(aS);
581
582     }
583
584     // Deleted vertices
585     anExp1.Init(myShape, TopAbs_VERTEX);
586     for(; anExp1.More();  anExp1.Next()) {
587       const TopoDS_Shape& aV = anExp1.Current();
588       aComVerMap.Remove(aV);
589     }
590
591     anI2.Initialize(aComVerMap);
592     for(; anI2.More(); anI2.Next()) {
593       // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind(anI2.Key(), TopTools_ListOfShape());
594       TopTools_ListOfShape aListOfShape3;
595       myMapModif.Bind(anI2.Key(), aListOfShape3);
596     }
597               
598     Done();
599   }
600
601   return;
602
603 }
604
605 // @@SDM: begin
606
607 // Copyright SAMTECH ..........................................Version    3.0-00
608 // Lastly modified by : pat                                    Date :   01/07/04
609
610 // File history synopsis (creation,modification,correction)
611 // +---------------------------------------------------------------------------+
612 // ! Developer !              Comments                   !   Date   ! Version  !
613 // +-----------!-----------------------------------------!----------!----------+
614 // !       skv ! Creation                                ! 5-05-2001! 3.0-00-3!
615 // !       skv ! Adaptation to OCC version 5.0           ! 6-05-2003! 3.0-00-2!
616 // !  vladimir ! adaptation to CAS 5.0                   !  07/01/03!    4.0-2!
617 // !       pat ! fix for 4086                            !  01/07/04!    4.2-3!
618 // +---------------------------------------------------------------------------+
619 //
620 // @@SDM: end