Salome HOME
Dump Image data to python script (Feature #13).
[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   FACTORY->myOps[QString(typeid(*theOperator).name())] = theOperator;
42 }
43
44 HYDROOperations_Factory::HYDROOperations_Factory()
45 {
46 }
47
48 ImageComposer_Operator* HYDROOperations_Factory::Operator(
49   Handle(HYDROData_Image) theImage) const
50 {
51   // retreive operator instance by name
52   ImageComposer_Operator* anOp = Operator(theImage->OperatorName());
53   if (!anOp)
54     return anOp;
55   // fill arguments of the operator from theImage
56   theImage->Args();
57   anOp->setBinArgs(theImage->Args());
58   return anOp;
59 }
60
61 Handle(HYDROData_Image) HYDROOperations_Factory::CreateImage(
62   Handle(HYDROData_Document) theDoc, const ImageComposer_Operator* theOperator)
63 {
64   // create an object
65   Handle(HYDROData_Image) anImage = 
66     Handle(HYDROData_Image)::DownCast(theDoc->CreateObject(KIND_IMAGE));
67   // get data from operation
68   if (theOperator) {
69     anImage->SetOperatorName(QString(typeid(*theOperator).name()));
70     anImage->SetArgs(theOperator->getBinArgs());
71   }
72   return anImage;
73 }
74
75 void HYDROOperations_Factory::UpdateImage(
76   Handle_HYDROData_Document theDoc, Handle(HYDROData_Image) theImage)
77 {
78   // fill by arguments and process the operation
79   ImageComposer_Operator* anOp = Operator(theImage);
80   if (anOp) { // update image only if there is an operation
81     QTransform aTransform;
82     ImageComposer_Image anImage1; // first referenced image
83     if (theImage->NbReferences()) {
84       Handle(HYDROData_Image) anImage = theImage->Reference(0);
85       anImage1 = anImage->Image();
86       anImage1.setTransform(anImage->Trsf());
87       aTransform = anImage1.transform();
88     }
89     ImageComposer_Image anImage2; // second referenced image
90     if (theImage->NbReferences() > 1) {
91       Handle(HYDROData_Image) anImage = theImage->Reference(1);
92       anImage2 = anImage->Image();
93       anImage2.setTransform(anImage->Trsf());
94     }
95     ImageComposer_Image aResImg = anOp->process(anImage1, anImage2);
96     theImage->SetImage(aResImg);
97     theImage->SetTrsf(aTransform);
98   }
99   // change the states of this and all depended images
100   theImage->MustBeUpdated(true);
101   SetMustBeUpdatedImages(theDoc);
102   theImage->MustBeUpdated(false);
103 }
104
105 void HYDROOperations_Factory::SetMustBeUpdatedImages(
106   Handle_HYDROData_Document theDoc) const
107 {
108   bool aChanged = true;
109   // iterate until there is no changes because images on all level of dependency must be updated
110   while(aChanged) {
111     aChanged = false;
112     HYDROData_Iterator anIter(theDoc, KIND_IMAGE);
113     for(; anIter.More(); anIter.Next()) {
114       Handle(HYDROData_Image) anImage = 
115         Handle(HYDROData_Image)::DownCast(anIter.Current());
116       if (!anImage->MustBeUpdated()) {
117         int a, aNBRefs = anImage->NbReferences();
118         for(a = 0; a < aNBRefs; a++) {
119           if (anImage->Reference(a)->MustBeUpdated()) {
120              // image references to updated => also must be updated
121              anImage->MustBeUpdated(true);
122              aChanged = true;
123           }
124         }
125       }
126     }
127   }
128 }