84c2a0998dba5cc71900c805f789a0ccfa2609a1
[occt.git] / src / XCAFDoc / XCAFDoc_ColorTool.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #include <XCAFDoc_ColorTool.ixx>
19 #include <XCAFDoc.hxx>
20 #include <XCAFDoc_Color.hxx>
21
22 #include <TDF_ChildIDIterator.hxx>
23 #include <TDataStd_TreeNode.hxx>
24 #include <TDataStd_Name.hxx>
25 #include <TNaming_NamedShape.hxx>
26 #include <XCAFDoc_DocumentTool.hxx>
27 #include <XCAFDoc_Color.hxx>
28 #include <TDataStd_UAttribute.hxx>
29 #include <XCAFDoc_GraphNode.hxx>
30
31 #define AUTONAMING // automatically set names for labels
32
33 //=======================================================================
34 //function : BaseLabel
35 //purpose  : 
36 //=======================================================================
37
38 TDF_Label XCAFDoc_ColorTool::BaseLabel() const
39 {
40   return Label();
41 }
42 //=======================================================================
43 //function : ShapeTool
44 //purpose  : 
45 //=======================================================================
46
47 const Handle(XCAFDoc_ShapeTool)& XCAFDoc_ColorTool::ShapeTool() 
48 {
49   if (myShapeTool.IsNull())
50     myShapeTool = XCAFDoc_DocumentTool::ShapeTool(Label());
51   return myShapeTool;
52 }
53
54
55 //=======================================================================
56 //function : IsColor
57 //purpose  : 
58 //=======================================================================
59
60 Standard_Boolean XCAFDoc_ColorTool::IsColor (const TDF_Label& lab) const
61 {
62   Quantity_Color C;
63   return GetColor ( lab, C );
64 }
65
66 //=======================================================================
67 //function : GetColor
68 //purpose  : 
69 //=======================================================================
70
71 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& lab,
72                                                Quantity_Color& col) const
73 {
74   if ( lab.Father() != Label() ) return Standard_False;
75   
76   Handle(XCAFDoc_Color) ColorAttribute;
77   if ( ! lab.FindAttribute ( XCAFDoc_Color::GetID(), ColorAttribute ))
78     return Standard_False;
79   
80   col = ColorAttribute->GetColor();
81   
82   return Standard_True;
83 }
84
85 //=======================================================================
86 //function : FindColor
87 //purpose  : 
88 //=======================================================================
89
90 Standard_Boolean XCAFDoc_ColorTool::FindColor (const Quantity_Color& col, TDF_Label& lab) const
91 {
92   TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
93   for (; it.More(); it.Next()) {
94     TDF_Label aLabel = it.Value()->Label();
95     Quantity_Color C;
96     if ( ! GetColor ( aLabel, C ) ) continue;
97     if ( C.IsEqual ( col ) ) {
98       lab = aLabel;
99       return Standard_True;
100     }
101   }
102   return Standard_False;
103 }
104
105 //=======================================================================
106 //function : FindColor
107 //purpose  : 
108 //=======================================================================
109
110 TDF_Label XCAFDoc_ColorTool::FindColor (const Quantity_Color& col) const
111 {
112   TDF_Label L;
113   FindColor ( col, L );
114   return L;
115 }
116
117 //=======================================================================
118 //function : AddColor
119 //purpose  : 
120 //=======================================================================
121
122 TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_Color& col) const
123 {
124   TDF_Label L;
125   if ( FindColor ( col, L ) ) return L;
126
127   // create a new color entry
128   
129   TDF_TagSource aTag;
130   L = aTag.NewChild ( Label() );
131
132   XCAFDoc_Color::Set(L, col);
133   
134 #ifdef AUTONAMING
135   // set name according to color value
136   TCollection_AsciiString str;
137   str += col.StringName ( col.Name() );
138   str += " (";
139   str += TCollection_AsciiString ( col.Red() );
140   str += ",";
141   str += TCollection_AsciiString ( col.Green() );
142   str += ",";
143   str += TCollection_AsciiString ( col.Blue() );
144   str += ")";
145   TDataStd_Name::Set ( L, str );
146 #endif
147   
148   return L;
149 }
150
151 //=======================================================================
152 //function : RemoveColor
153 //purpose  : 
154 //=======================================================================
155
156 void XCAFDoc_ColorTool::RemoveColor (const TDF_Label& lab) const
157 {
158   lab.ForgetAllAttributes (Standard_True);
159 }
160
161 //=======================================================================
162 //function : GetColors
163 //purpose  : 
164 //=======================================================================
165
166 void XCAFDoc_ColorTool::GetColors (TDF_LabelSequence& Labels) const
167 {
168   Labels.Clear();
169
170   TDF_ChildIDIterator ChildIDIterator(Label(),XCAFDoc_Color::GetID()); 
171   for (; ChildIDIterator.More(); ChildIDIterator.Next()) {
172     TDF_Label L = ChildIDIterator.Value()->Label();
173     if ( IsColor ( L ) ) Labels.Append ( L );
174   }
175 }
176
177 //=======================================================================
178 //function : SetColor
179 //purpose  : 
180 //=======================================================================
181
182 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
183                                const TDF_Label& colorL,
184                                const XCAFDoc_ColorType type) const
185 {
186   // set reference
187   Handle(TDataStd_TreeNode) refNode, mainNode;
188   mainNode = TDataStd_TreeNode::Set ( colorL, XCAFDoc::ColorRefGUID(type) );
189   refNode  = TDataStd_TreeNode::Set ( L,      XCAFDoc::ColorRefGUID(type) );
190   refNode->Remove(); // abv: fix against bug in TreeNode::Append()
191   mainNode->Prepend(refNode);
192 }
193
194 //=======================================================================
195 //function : SetColor
196 //purpose  : 
197 //=======================================================================
198
199 void XCAFDoc_ColorTool::SetColor (const TDF_Label& L,
200                                const Quantity_Color& Color,
201                                const XCAFDoc_ColorType type) const
202 {
203   TDF_Label colorL = AddColor ( Color );
204   SetColor ( L, colorL, type );
205 }
206
207 //=======================================================================
208 //function : UnSetColor
209 //purpose  : 
210 //=======================================================================
211
212 void XCAFDoc_ColorTool::UnSetColor (const TDF_Label& L, const XCAFDoc_ColorType type) const
213 {
214   L.ForgetAttribute ( XCAFDoc::ColorRefGUID(type) );
215 }
216
217 //=======================================================================
218 //function : IsSet
219 //purpose  : 
220 //=======================================================================
221
222 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TDF_Label& L, const XCAFDoc_ColorType type) const
223 {
224   Handle(TDataStd_TreeNode) Node;
225   return L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) && Node->HasFather();
226 }
227
228 //=======================================================================
229 //function : GetColor
230 //purpose  : 
231 //=======================================================================
232
233 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
234                                            const XCAFDoc_ColorType type,
235                                            TDF_Label& colorL) 
236 {
237   Handle(TDataStd_TreeNode) Node;
238   if ( ! L.FindAttribute ( XCAFDoc::ColorRefGUID(type), Node) ||
239        ! Node->HasFather() ) return Standard_False;
240   colorL = Node->Father()->Label();
241   return Standard_True;
242 }
243
244 //=======================================================================
245 //function : GetColor
246 //purpose  : 
247 //=======================================================================
248
249 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TDF_Label& L,
250                                            const XCAFDoc_ColorType type,
251                                            Quantity_Color& color) 
252 {
253   TDF_Label colorL;
254   if ( ! GetColor ( L, type, colorL ) ) return Standard_False;
255   return GetColor ( colorL, color );
256 }
257
258 //=======================================================================
259 //function : SetColor
260 //purpose  : 
261 //=======================================================================
262
263 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
264                                            const TDF_Label& colorL,
265                                            const XCAFDoc_ColorType type) 
266 {
267   TDF_Label L;
268   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
269   SetColor ( L, colorL, type );
270   return Standard_True;
271 }
272
273 //=======================================================================
274 //function : SetColor
275 //purpose  : 
276 //=======================================================================
277
278 Standard_Boolean XCAFDoc_ColorTool::SetColor (const TopoDS_Shape& S,
279                                            const Quantity_Color& Color,
280                                            const XCAFDoc_ColorType type) 
281 {
282   TDF_Label colorL = AddColor ( Color );
283   return SetColor ( S, colorL, type );
284 }
285
286 //=======================================================================
287 //function : UnSetColor
288 //purpose  : 
289 //=======================================================================
290
291 Standard_Boolean XCAFDoc_ColorTool::UnSetColor (const TopoDS_Shape& S,
292                                              const XCAFDoc_ColorType type) 
293 {
294   TDF_Label L;
295   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
296   UnSetColor ( L, type );
297   return Standard_True;
298 }
299
300 //=======================================================================
301 //function : IsSet
302 //purpose  : 
303 //=======================================================================
304
305 Standard_Boolean XCAFDoc_ColorTool::IsSet (const TopoDS_Shape& S,
306                                         const XCAFDoc_ColorType type) 
307 {
308   TDF_Label L;
309   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
310   return IsSet ( L, type );
311 }
312
313 //=======================================================================
314 //function : GetColor
315 //purpose  : 
316 //=======================================================================
317
318 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S, 
319                                            const XCAFDoc_ColorType type,
320                                            TDF_Label& colorL) 
321 {
322   TDF_Label L;
323   if ( ! ShapeTool()->Search ( S, L ) ) return Standard_False;
324   return GetColor ( L, type, colorL );
325 }
326
327 //=======================================================================
328 //function : GetColor
329 //purpose  : 
330 //=======================================================================
331
332 Standard_Boolean XCAFDoc_ColorTool::GetColor (const TopoDS_Shape& S,
333                                            const XCAFDoc_ColorType type,
334                                            Quantity_Color& color) 
335 {
336   TDF_Label colorL;
337   if ( ! GetColor ( S, type, colorL ) ) return Standard_False;
338   return GetColor ( colorL, color );
339 }
340
341 //=======================================================================
342 //function : GetID
343 //purpose  : 
344 //=======================================================================
345
346 const Standard_GUID& XCAFDoc_ColorTool::GetID() 
347 {
348   static Standard_GUID ColorTblID ("efd212ed-6dfd-11d4-b9c8-0060b0ee281b");
349   return ColorTblID; 
350 }
351
352 //=======================================================================
353 //function : Set
354 //purpose  : 
355 //=======================================================================
356
357 Handle(XCAFDoc_ColorTool) XCAFDoc_ColorTool::Set(const TDF_Label& L) 
358 {
359   Handle(XCAFDoc_ColorTool) A;
360   if (!L.FindAttribute (XCAFDoc_ColorTool::GetID(), A)) {
361     A = new XCAFDoc_ColorTool ();
362     L.AddAttribute(A);
363     A->myShapeTool = XCAFDoc_DocumentTool::ShapeTool(L);
364   }
365   return A;
366 }
367
368 //=======================================================================
369 //function : ID
370 //purpose  : 
371 //=======================================================================
372
373 const Standard_GUID& XCAFDoc_ColorTool::ID() const
374 {
375   return GetID();
376 }
377
378 //=======================================================================
379 //function : Restore
380 //purpose  : 
381 //=======================================================================
382
383 void XCAFDoc_ColorTool::Restore(const Handle(TDF_Attribute)& /*with*/) 
384 {
385 }
386
387 //=======================================================================
388 //function : NewEmpty
389 //purpose  : 
390 //=======================================================================
391
392 Handle(TDF_Attribute) XCAFDoc_ColorTool::NewEmpty() const
393 {
394   return new XCAFDoc_ColorTool;
395 }
396
397 //=======================================================================
398 //function : Paste
399 //purpose  : 
400 //=======================================================================
401
402 void XCAFDoc_ColorTool::Paste (const Handle(TDF_Attribute)& /*into*/,
403                                const Handle(TDF_RelocationTable)& /*RT*/) const
404 {
405 }
406
407 /**/
408
409 //=======================================================================
410 //function : XCAFDoc_ColorTool
411 //purpose  : 
412 //=======================================================================
413
414 XCAFDoc_ColorTool::XCAFDoc_ColorTool()
415 {
416 }
417
418 // PTV 23.01.2003 add visibility flag for objects (CAX-IF TRJ11)
419 //=======================================================================
420 //function : IsVisible
421 //purpose  : 
422 //=======================================================================
423
424 Standard_Boolean XCAFDoc_ColorTool::IsVisible (const TDF_Label& L) const
425 {
426   Handle(TDataStd_UAttribute) aUAttr;
427   return (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr));
428 }
429
430 //=======================================================================
431 //function : SetVisibility
432 //purpose  : 
433 //=======================================================================
434
435 void XCAFDoc_ColorTool::SetVisibility (const TDF_Label& L,
436                                        const Standard_Boolean isvisible)
437 {
438   Handle(TDataStd_UAttribute) aUAttr;
439   if (! isvisible ) {
440     Handle(XCAFDoc_GraphNode) aSHUO;
441     if (ShapeTool()->IsShape(L) || ShapeTool()->GetSHUO( L, aSHUO ) )
442       if (!L.FindAttribute(XCAFDoc::InvisibleGUID(), aUAttr))
443         aUAttr->Set( L, XCAFDoc::InvisibleGUID() );
444   }
445   else L.ForgetAttribute( XCAFDoc::InvisibleGUID() );
446 }
447
448 //=======================================================================
449 //function : SetInstanceColor
450 //purpose  : 
451 //=======================================================================
452
453 Standard_Boolean XCAFDoc_ColorTool::SetInstanceColor (const TopoDS_Shape& theShape,
454                                                       const XCAFDoc_ColorType type,
455                                                       const Quantity_Color& color,
456                                                       const Standard_Boolean IsCreateSHUO)
457 {
458   // find shuo label structure 
459   TDF_LabelSequence aLabels;
460   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
461     return Standard_False;
462   Handle(XCAFDoc_GraphNode) aSHUO;
463   // set the SHUO structure for this component if it is not exist
464   if ( !ShapeTool()->FindSHUO( aLabels, aSHUO ) )
465     if (aLabels.Length() == 1) {
466       // set color directly for component as NAUO
467       SetColor(aLabels.Value(1), color, type);
468       return Standard_True;
469     }
470     else if ( !IsCreateSHUO ||  !ShapeTool()->SetSHUO( aLabels, aSHUO ) )
471       return Standard_False;
472   TDF_Label aSHUOLabel = aSHUO->Label();
473   SetColor( aSHUOLabel, color, type );
474   return Standard_True;
475 }
476
477 //=======================================================================
478 //function : GetInstanceColor
479 //purpose  : 
480 //=======================================================================
481
482 Standard_Boolean XCAFDoc_ColorTool::GetInstanceColor (const TopoDS_Shape& theShape,
483                                                       const XCAFDoc_ColorType type,
484                                                       Quantity_Color& color)
485 {
486   // find shuo label structure 
487   TDF_LabelSequence aLabels;
488   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
489     return Standard_False;
490   Handle(XCAFDoc_GraphNode) aSHUO;
491   // get shuo from document by label structure
492   TDF_Label aCompLab = aLabels.Value(aLabels.Length());
493   while (aLabels.Length() > 1) {
494     if ( !ShapeTool()->FindSHUO( aLabels, aSHUO ) ) {
495       // try to find other shuo 
496       aLabels.Remove(aLabels.Length());
497       continue;
498     } else {
499       TDF_Label aSHUOLabel = aSHUO->Label();
500       if (GetColor ( aSHUOLabel, type, color ) )
501         return Standard_True;
502       else 
503         // try to find other shuo 
504         aLabels.Remove(aLabels.Length());
505     }
506   }
507   // attempt to get color exactly of component
508   if (GetColor( aCompLab, type, color ))
509     return Standard_True;
510   
511   // attempt to get color of solid
512   TopLoc_Location aLoc;
513   TopoDS_Shape S0 = theShape;
514   S0.Location( aLoc );
515   TDF_Label aRefLab = ShapeTool()->FindShape( S0 );
516   if (!aRefLab.IsNull())
517     return GetColor( aRefLab, type, color );
518   // no color assigned
519   return Standard_False;
520 }
521
522 //=======================================================================
523 //function : IsInstanceVisible
524 //purpose  : 
525 //=======================================================================
526
527 Standard_Boolean XCAFDoc_ColorTool::IsInstanceVisible (const TopoDS_Shape& theShape)
528 {
529   // check visibility status of top-level solid, cause it is have highest priority
530   TopLoc_Location NullLoc;
531   TopoDS_Shape S0 = theShape;
532   S0.Location( NullLoc );
533   TDF_Label aRefL = ShapeTool()->FindShape( S0 );
534   if (!aRefL.IsNull() && !IsVisible(aRefL))
535     return Standard_False;
536   // find shuo label structure 
537   TDF_LabelSequence aLabels;
538   if ( !ShapeTool()->FindComponent( theShape, aLabels ) )
539     return Standard_True;
540   TDF_Label aCompLab = aLabels.Value(aLabels.Length());
541   // visibility status of component withouts SHUO.
542   if (!IsVisible( aCompLab ))
543     return Standard_False;
544   // check by SHUO structure
545   TDF_LabelSequence aCurLabels;
546   aCurLabels.Append(aCompLab);
547   Standard_Integer i = aLabels.Length() - 1;
548   //   while (aCurLabels.Length() < aLabels.Length()) {
549   while (i >= 1) {
550     aCurLabels.Prepend( aLabels.Value(i--) );
551     // get shuo from document by label structure
552     Handle(XCAFDoc_GraphNode) aSHUO;
553     if ( !ShapeTool()->FindSHUO( aCurLabels, aSHUO ) )
554       continue;
555     if ( !IsVisible(aSHUO->Label()) )
556       return Standard_False;
557   }
558   return Standard_True; //visible, cause cannot find invisibility status
559 }
560
561
562 //=======================================================================
563 //function : ReverseTreeNodes
564 //purpose  : auxilary
565 //=======================================================================
566 static void ReverseTreeNodes(Handle(TDataStd_TreeNode)& mainNode)
567 {
568   if(mainNode->HasFirst()) {
569     Handle(TDataStd_TreeNode) tmpNode;
570     Handle(TDataStd_TreeNode) pNode = mainNode->First();
571     Handle(TDataStd_TreeNode) nNode = pNode->Next();
572     while(!nNode.IsNull()) {
573       tmpNode = pNode->Previous();
574       pNode->SetPrevious(nNode);
575       pNode->SetNext(tmpNode);
576       pNode = nNode;
577       nNode = pNode->Next();
578     }
579     tmpNode = pNode->Previous();
580     pNode->SetPrevious(nNode);
581     pNode->SetNext(tmpNode);
582     mainNode->SetFirst(pNode);
583   }
584 }
585
586
587 //=======================================================================
588 //function : ReverseChainsOfTreeNodes
589 //purpose  : 
590 //=======================================================================
591
592 Standard_Boolean XCAFDoc_ColorTool::ReverseChainsOfTreeNodes()
593 {
594   TDF_ChildIDIterator it(Label(),XCAFDoc_Color::GetID());
595   for (; it.More(); it.Next()) {
596     TDF_Label aLabel = it.Value()->Label();
597     Handle(TDataStd_TreeNode) mainNode;
598     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorSurf),mainNode)) {
599       ReverseTreeNodes(mainNode);
600     }
601     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorCurv),mainNode)) {
602       ReverseTreeNodes(mainNode);
603     }
604     if(aLabel.FindAttribute(XCAFDoc::ColorRefGUID(XCAFDoc_ColorGen),mainNode)) {
605       ReverseTreeNodes(mainNode);
606     }
607   }
608   return Standard_True;
609 }