Salome HOME
Registerring of operators changed to cross platform maner.
[modules/hydro.git] / src / HYDROData / HYDROOperations_Factory.cxx
1 #include<HYDROOperations_Factory.h>
2
3 #include<HYDROData_Document.h>
4 #include<HYDROData_Iterator.h>
5
6 #include<ImageComposer_ColorMaskOperator.h>
7 #include<ImageComposer_CropOperator.h>
8 #include<ImageComposer_CutOperator.h>
9 #include<ImageComposer_FuseOperator.h>
10 #include<ImageComposer_Image.h>
11
12 #include <typeinfo>
13
14 // global instance
15 HYDROOperations_Factory* FACTORY = 0;
16
17 HYDROOperations_Factory* HYDROOperations_Factory::Factory()
18 {
19   if (!FACTORY) {
20     FACTORY = new HYDROOperations_Factory;
21     // default operations
22     REGISTER_HYDRO_OPERATION(ImageComposer_ColorMaskOperator)
23     REGISTER_HYDRO_OPERATION(ImageComposer_CropOperator)
24     REGISTER_HYDRO_OPERATION(ImageComposer_CutOperator)
25     REGISTER_HYDRO_OPERATION(ImageComposer_FuseOperator)
26   }
27   return FACTORY;
28 }
29
30 ImageComposer_Operator* HYDROOperations_Factory::Operator(const QString theName) const
31 {
32   if (myOps.contains(theName)) {
33     return myOps[theName];
34   }
35   return NULL;
36 }
37
38 void HYDROOperations_Factory::Register(
39   ImageComposer_Operator* theOperator)
40 {
41   if ( !theOperator )
42     return;
43
44   FACTORY->myOps[ theOperator->name() ] = theOperator;
45 }
46
47 HYDROOperations_Factory::HYDROOperations_Factory()
48 {
49 }
50
51 ImageComposer_Operator* HYDROOperations_Factory::Operator(
52   Handle(HYDROData_Image) theImage) const
53 {
54   // retreive operator instance by name
55   ImageComposer_Operator* anOp = Operator(theImage->OperatorName());
56   if (!anOp)
57     return anOp;
58   // fill arguments of the operator from theImage
59   theImage->Args();
60   anOp->setBinArgs(theImage->Args());
61   return anOp;
62 }
63
64 Handle(HYDROData_Image) HYDROOperations_Factory::CreateImage(
65   Handle(HYDROData_Document) theDoc, const ImageComposer_Operator* theOperator)
66 {
67   // create an object
68   Handle(HYDROData_Image) anImage = 
69     Handle(HYDROData_Image)::DownCast(theDoc->CreateObject(KIND_IMAGE));
70   // get data from operation
71   if (theOperator) {
72     anImage->SetOperatorName( theOperator->name() );
73     anImage->SetArgs( theOperator->getBinArgs() );
74   }
75   return anImage;
76 }
77
78 void HYDROOperations_Factory::UpdateImage(
79   Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage)
80 {
81   // fill by arguments and process the operation
82   ImageComposer_Operator* anOp = Operator(theImage);
83   if (anOp) { // update image only if there is an operation
84     QTransform aTransform;
85     ImageComposer_Image anImage1; // first referenced image
86     if (theImage->NbReferences()) {
87       Handle(HYDROData_Image) anImage =
88         Handle(HYDROData_Image)::DownCast( theImage->Reference(0) );
89       if( !anImage.IsNull() )
90       {
91         anImage1 = anImage->Image();
92         anImage1.setTransform(anImage->Trsf());
93         aTransform = anImage1.transform();
94       }
95     }
96     ImageComposer_Image anImage2; // second referenced image
97     if (theImage->NbReferences() > 1) {
98       Handle(HYDROData_Image) anImage =
99         Handle(HYDROData_Image)::DownCast( theImage->Reference(1) );
100       if( !anImage.IsNull() )
101       {
102         anImage2 = anImage->Image();
103         anImage2.setTransform(anImage->Trsf());
104       }
105     }
106     ImageComposer_Image aResImg = anOp->process(anImage1, anImage2);
107     theImage->SetImage(aResImg);
108     theImage->SetTrsf(aTransform);
109   }
110   // change the states of this and all depended images
111   theImage->MustBeUpdated(true);
112   SetMustBeUpdatedImages(theDoc);
113   theImage->MustBeUpdated(false);
114 }
115
116 void HYDROOperations_Factory::SetMustBeUpdatedImages(
117   Handle_HYDROData_Document theDoc) const
118 {
119   bool aChanged = true;
120   // iterate until there is no changes because images on all level of dependency must be updated
121   while(aChanged) {
122     aChanged = false;
123     HYDROData_Iterator anIter(theDoc, KIND_IMAGE);
124     for(; anIter.More(); anIter.Next()) {
125       Handle(HYDROData_Image) anImage = 
126         Handle(HYDROData_Image)::DownCast(anIter.Current());
127       if (!anImage->MustBeUpdated()) {
128         int a, aNBRefs = anImage->NbReferences();
129         for(a = 0; a < aNBRefs; a++) {
130           Handle(HYDROData_Image) aRefImage =
131             Handle(HYDROData_Image)::DownCast(anImage->Reference(a));
132           if (!aRefImage.IsNull() && aRefImage->MustBeUpdated()) {
133              // image references to updated => also must be updated
134              anImage->MustBeUpdated(true);
135              aChanged = true;
136           }
137         }
138       }
139     }
140   }
141 }