Salome HOME
updated copyright message
[samples/sierpinsky.git] / src / Sierpinsky / SIERPINSKY_Gen_i.cxx
1 // Copyright (C) 2005-2023  OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 ///////////////////////////////////////////////////////////
21 // File    : SIERPINSKY_Gen_i.cxx
22 // Author  : Vadim SANDLER (OCN)
23 // Created : 13/07/05
24 ///////////////////////////////////////////////////////////
25
26 #include "SIERPINSKY_Gen_i.hxx"
27 #include "SIERPINSKY_version.h"
28 #include <MED_Factory.hxx>
29 #ifdef WITH_LIBGD
30 #include <gd.h>
31 #endif // WITH_LIBGD
32
33 /*!
34  * Engine factory
35  */
36 extern "C"
37
38   SIERPINSKYENGINE_EXPORT
39   PortableServer::ObjectId * SIERPINSKYEngine_factory( CORBA::ORB_ptr            orb,
40                                                        PortableServer::POA_ptr   poa, 
41                                                        PortableServer::ObjectId* contId,
42                                                        const char*               instanceName,
43                                                        const char*               interfaceName )
44 {
45   SIERPINSKY_Gen_i* anEngine = new SIERPINSKY_Gen_i( orb, poa, contId, instanceName, interfaceName );
46   return anEngine->getId() ;
47 }
48 }
49
50 /*!
51  * Default constructor
52  */
53 SIERPINSKY_Gen_i::SIERPINSKY_Gen_i()
54 {
55 }
56
57 /*!
58  * Constructor
59  */
60 SIERPINSKY_Gen_i::SIERPINSKY_Gen_i( CORBA::ORB_ptr            orb,
61                                     PortableServer::POA_ptr   poa,
62                                     PortableServer::ObjectId* contId, 
63                                     const char*               instanceName, 
64                                     const char*               interfaceName ) 
65 : Engines_Component_i( orb, poa, contId, instanceName, interfaceName ) 
66 {
67   // activate servant
68   _thisObj = this;
69   _id = poa->activate_object(_thisObj);
70   // set default values
71   Reset();
72 }
73
74 /*!
75  * Destructor
76  */
77 SIERPINSKY_Gen_i::~SIERPINSKY_Gen_i()
78 {
79   myPoints.clear();
80 }
81   
82 /*!
83  * Initializes engine with three reference points
84  */
85 void SIERPINSKY_Gen_i::Init( CORBA::Double theX1, CORBA::Double theY1, 
86                              CORBA::Double theX2, CORBA::Double theY2, 
87                              CORBA::Double theX3, CORBA::Double theY3 )
88 {
89   myRefPoints[0] = MyPoint( theX1, theY1 );
90   myRefPoints[1] = MyPoint( theX2, theY2 );
91   myRefPoints[2] = MyPoint( theX3, theY3 );
92   myPoints.clear();
93 }
94   
95 /*!
96  * Initializes engine with three default reference points: (0.5, 1), (0, 0), (1, 0)
97  */
98 void SIERPINSKY_Gen_i::Reset()
99 {
100   myRefPoints[0] = MyPoint( 0.5, 1.0 );
101   myRefPoints[1] = MyPoint( 0.0, 0.0 );
102   myRefPoints[2] = MyPoint( 1.0, 0.0 );
103   myPoints.clear();
104 }
105   
106 /*!
107  * Generates next iteration point
108  */
109 void SIERPINSKY_Gen_i::NextPoint( CORBA::Double  theX,     CORBA::Double  theY, 
110                                   CORBA::Long    theIter, 
111                                   CORBA::Double& theNextX, CORBA::Double& theNextY )
112 {
113   double x = theIter < 1 || theIter > 3 ? theX : ( theX + myRefPoints[ theIter-1 ].myX ) / 2;
114   double y = theIter < 1 || theIter > 3 ? theY : ( theY + myRefPoints[ theIter-1 ].myY ) / 2;
115   myPoints.push_back( MyPoint( x, y ) );
116   theNextX = x;
117   theNextY = y;
118 }
119   
120 /*!
121  * Exports data to the JPEG image
122  */
123 CORBA::Boolean SIERPINSKY_Gen_i::ExportToJPEG( const char* theFileName, CORBA::Long theSize )
124 {
125 #ifdef WITH_LIBGD
126   if ( theSize <= 0 ) return false;
127
128   // open file
129   FILE* fileDescriptor = fopen( theFileName, "wb" );
130   if ( !fileDescriptor ) return false;
131
132   // create an image
133   gdImagePtr image = gdImageCreate( theSize, theSize );
134   int white = gdImageColorAllocate( image, 255, 255, 255 );
135   int black = gdImageColorAllocate( image,   0,   0,   0 );
136
137   gdImageRectangle( image, 0, 0, theSize-1, theSize-1, white );
138
139   // draw points
140   std::list<MyPoint>::const_iterator iter;
141   for ( iter = myPoints.begin(); iter != myPoints.end(); ++iter ) {
142     gdImageSetPixel( image, (int)( (*iter).myX * theSize ), theSize - (int)( (*iter).myY * theSize ), black );
143   }
144
145   // export jpeg image
146   gdImageJpeg( image, fileDescriptor, 95 );
147   fclose( fileDescriptor );
148   gdImageDestroy( image );
149   
150   return true;
151 #else // WITH_LIBGD
152   printf("Warning: ExportToJPEG() is not supported (libgd is required)!");
153   return false;
154 #endif // WITH_LIBGD
155 }
156   
157 /*!
158  * Exports data to the MED file
159  */
160 CORBA::Boolean SIERPINSKY_Gen_i::ExportToMED( const char* theFileName, CORBA::Double theSize )
161 {
162   MED::TErr anError;
163   
164   // if file already exists - remove it (MED cannot overwrite files correctly)
165   FILE* aFile = fopen( theFileName, "rb" );
166   if ( aFile ) {
167     fclose( aFile );
168     if ( remove( theFileName ) ) return false; // can't remove file
169   }
170   
171   // create MED 2.2 file
172   MED::PWrapper aMed = MED::CrWrapperW( theFileName );
173
174   // create 2D mesh
175   MED::PMeshInfo aMesh = aMed->CrMeshInfo( 2, 2, "Sierpinsky" );
176   aMed->SetMeshInfo( aMesh, &anError );
177   if ( anError < 0 ) return false;
178
179   // create nodes
180   MED::TFloatVector nodes;
181   MED::TIntVector   connect;
182   std::list<MyPoint>::const_iterator iter;
183   int ind = 1;
184   for ( iter = myPoints.begin(); iter != myPoints.end(); ++iter ) {
185     nodes.push_back( (*iter).myX * theSize );
186     nodes.push_back( (*iter).myY * theSize );
187     connect.push_back( ind++ );
188   }
189   MED::PNodeInfo aNodes = aMed->CrNodeInfo( aMesh, nodes, 
190                                             MED::eFULL_INTERLACE, MED::eCART, 
191                                             MED::TStringVector(2),
192                                             MED::TStringVector(2), 
193                                             MED::TIntVector( myPoints.size() ),
194                                             MED::TIntVector() );
195   aMed->SetNodeInfo( aNodes, &anError );
196   if ( anError < 0 ) return false;
197
198   MED::PCellInfo aCells = aMed->CrCellInfo( aMesh, MED::eMAILLE, MED::ePOINT1, 
199                                             connect, MED::eNOD, 
200                                             MED::TIntVector( myPoints.size() ), 
201                                             MED::TIntVector( myPoints.size() ) );
202   aMed->SetCellInfo( aCells, &anError );
203   if ( anError < 0 ) return false;
204
205   return true;
206 }
207
208 // Version information
209 char* SIERPINSKY_Gen_i::getVersion()
210 {
211 #if SIERPINSKY_DEVELOPMENT
212   return CORBA::string_dup(SIERPINSKY_VERSION_STR"dev");
213 #else
214   return CORBA::string_dup(SIERPINSKY_VERSION_STR);
215 #endif
216 }