11#include "arcane/IMesh.h"
12#include "arcane/IApplication.h"
13#include "arcane/IParallelMng.h"
14#include "arcane/IVariableMng.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/IVariableAccessor.h"
17#include "arcane/FactoryService.h"
18#include "arcane/ServiceFinder2.h"
19#include "arcane/SharedVariable.h"
20#include "arcane/CommonVariables.h"
21#include "arcane/utils/ScopedPtr.h"
22#include "arcane/AbstractService.h"
23#include "arcane/VariableCollection.h"
25#include "arcane/utils/PlatformUtils.h"
26#include "arcane/utils/IOnlineDebuggerService.h"
27#include "arcane/ITransferValuesParallelOperation.h"
29#include "arcane/IVariableAccessor.h"
30#include <arcane/IParticleFamily.h>
31#include "arcane/datatype/ArrayVariant.h"
34#define GL_MULTISAMPLE 0x809D
37#include "arcane/hyoda/HyodaIceTGlobal.h"
38#include "arcane/hyoda/Hyoda.h"
39#include "arcane/hyoda/HyodaArc.h"
40#include "arcane/hyoda/HyodaTcp.h"
41#include "arcane/hyoda/HyodaIceT.h"
42#include "arcane/hyoda/HyodaMix.h"
43extern void ppmWrite(
const char*,
const unsigned char*,
int width,
int height);
48 void drawGLCallback(
void){
49 if (!HyodaIceTCallbackHandle)
return;
50 HyodaIceTCallbackHandle->drawGL();
67HyodaIceT::HyodaIceT(Hyoda *hd,
72 HyodaTcp *_tcp): TraceAccessor(tm),
76 icetCommunicator(NULL),
78 rank(sd->parallelMng()->commRank()),
79 num_proc(sd->parallelMng()->commSize()),
90 m_hyoda_mix(new HyodaMix(hd,sd,tm)),
93 debug()<<
"\33[33m[HyodaIceT::HyodaIceT] New "
94 <<
", screen_width="<<m_screen_width
95 <<
", screen_height="<<m_screen_height
105 #warning Duplicated code here
107 VariableCollection variables = m_sub_domain->variableMng()->usedVariables();
108 for(VariableCollection::Enumerator ivar(variables); ++ivar; ){
109 IVariable* var = *ivar;
111 if (var->nbReference()==0) {debug() <<
"\33[33m[HyodaIceT::HyodaIceT] No nbReference\33[m";
continue;}
113 if (var->itemKind() != IK_Node &&
114 var->itemKind() != IK_Cell &&
115 var->itemKind() != IK_Face &&
116 var->itemKind() != IK_Particle)
continue;
118 if (var->itemKind() != IK_Particle && (!var->hasTag(
"PostProcessing")))
119 {debug() <<
"\33[33m[HyodaIceT::HyodaIceT] "<<var->name()<<
" not PostProcessing\33[m";
continue;}
122 if (var->dataType()!=DT_Real)
continue;
124 debug() <<
"\33[33m[HyodaIceT::HyodaIceT] m_variable is "<<var->name()<<
"\33[m";
128 ARCANE_FATAL(
"\33[33m[HyodaIceT::HyodaIceT] No m_variable to draw!\33[m");
129 debug()<<
"\33[33m[HyodaIceT::HyodaIceT] Focusing on variable: "<<m_variable->name()<<
"\33[m";
132 osMesaContext = OSMesaCreateContextExt(OSMESA_RGBA, 8, 0, 0, NULL);
133 if (!osMesaContext) fatal()<<
"OSMesaCreateContext failed!\n";
135 m_image_buffer=malloc(renderSize());
136 if (!m_image_buffer) fatal()<<
"Alloc image failed!\n";
138 if (!OSMesaMakeCurrent(osMesaContext,
143 fatal()<<
"OSMesaMakeCurrent failed!\n";
146 glGetIntegerv(GL_DEPTH_BITS, &z);
147 glGetIntegerv(GL_STENCIL_BITS, &s);
148 glGetIntegerv(GL_ACCUM_RED_BITS, &a);
149 debug()<<
"\33[33m[HyodaIceT] Depth="<<z<<
", Stencil="<<s<<
", Accum="<<a<<
"\33[m";
152 #warning IceT needs MPI_Init
153 IceTBitField diag_level = ICET_DIAG_ALL_NODES | ICET_DIAG_WARNINGS;
154 if (sd->parallelMng()->isParallel()){
155 debug() <<
"\33[33m[HyodaIceT] isParallel icetCreateMPICommunicator @"
156 << sd->parallelMng()->getMPICommunicator()<<
"\33[m";
157 icetCommunicator = icetCreateMPICommunicator(*(MPI_Comm*)sd->parallelMng()->getMPICommunicator());
159 debug()<<
"\33[33m[HyodaIceT] MPI_COMM_SELF icetCreateMPICommunicator\33[m";
160 icetCommunicator = icetCreateMPICommunicator(MPI_COMM_SELF);
162 icetContext = icetCreateContext(icetCommunicator);
166 icetGLDrawCallback(drawGLCallback);
167 HyodaIceTCallbackHandle=
this;
169 icetAddTile(0, 0, m_screen_width, m_screen_height, 0);
170 icetStrategy(ICET_STRATEGY_SEQUENTIAL);
171 icetSingleImageStrategy(ICET_SINGLE_IMAGE_STRATEGY_AUTOMATIC);
173 icetSetColorFormat(ICET_IMAGE_COLOR_RGBA_UBYTE);
174 icetSetDepthFormat(ICET_IMAGE_DEPTH_FLOAT);
175 icetCompositeMode(ICET_COMPOSITE_MODE_Z_BUFFER);
177 setLeftRightBottomTop();
178 Real length=lrbtnf[1]-lrbtnf[0];
179 Real height=lrbtnf[3]-lrbtnf[2];
180 icetBoundingBoxd(lrbtnf[0]-length, lrbtnf[1]+length, lrbtnf[2]-height, lrbtnf[3]+height, lrbtnf[4], lrbtnf[5]);
181 icetDisable(ICET_FLOATING_VIEWPORT);
182 icetEnable(ICET_ORDERED_COMPOSITE);
185 debug()<<
"\33[33m[HyodaIceT] checkOglError\33[m";
195void HyodaIceT::setLeftRightBottomTop(
void){
197 const VariableItemReal3 nodes_coords=m_sub_domain->defaultMesh()->nodesCoordinates();
198 debug()<<
"[HyodaIceT::setLeftRightBottomTop] mesh()->dimension()="<<m_sub_domain->mesh()->dimension();
199 lrbtnf[0]=lrbtnf[1]=lrbtnf[2]=lrbtnf[3]=0.0;
203 ENUMERATE_NODE(node,m_sub_domain->defaultMesh()->allCells().outerFaceGroup().nodeGroup()){
205 lrbtnf[0]=math::min(lrbtnf[0],nodes_coords[node].x);
206 lrbtnf[1]=math::max(lrbtnf[1],nodes_coords[node].x);
207 lrbtnf[2]=math::min(lrbtnf[2],nodes_coords[node].y);
208 lrbtnf[3]=math::max(lrbtnf[3],nodes_coords[node].y);
209 lrbtnf[4]=math::min(lrbtnf[4],nodes_coords[node].z);
210 lrbtnf[5]=math::max(lrbtnf[5],nodes_coords[node].z);
212 UniqueArray<Real> rdcMin(3);
213 UniqueArray<Real> rdcMax(3);
214 rdcMin[0]=scale*lrbtnf[0];
215 rdcMin[1]=scale*lrbtnf[2];
216 rdcMin[2]=scale*lrbtnf[4];
217 m_sub_domain->parallelMng()->reduce(Parallel::ReduceMin,rdcMin.view());
218 rdcMax[0]=scale*lrbtnf[1];
219 rdcMax[1]=scale*lrbtnf[3];
220 rdcMax[2]=scale*lrbtnf[5];
221 m_sub_domain->parallelMng()->reduce(Parallel::ReduceMax,rdcMax.view());
228 debug()<<
"\33[33m[HyodaIceT::setLeftRightBottomTop] left =" << lrbtnf[0]<<
"\33[m";
229 debug()<<
"\33[33m[HyodaIceT::setLeftRightBottomTop] right =" << lrbtnf[1]<<
"\33[m";
230 debug()<<
"\33[33m[HyodaIceT::setLeftRightBottomTop] bottom =" << lrbtnf[2]<<
"\33[m";
231 debug()<<
"\33[33m[HyodaIceT::setLeftRightBottomTop] top =" << lrbtnf[3]<<
"\33[m";
232 debug()<<
"\33[33m[HyodaIceT::setLeftRightBottomTop] near =" << lrbtnf[4]<<
"\33[m";
233 debug()<<
"\33[33m[HyodaIceT::setLeftRightBottomTop] far =" << lrbtnf[5]<<
"\33[m";
240void HyodaIceT::sxyzip(
double *pov){
245 debug()<<
"\33[33m[HyodaIceT::sxyzi] scale="<<scale<<
", rot_x="<<rot_x<<
", rot_y="<<rot_y<<
", rot_z="<<rot_z<<
"\33[m";
246 variable_index=(int)pov[4];
247 variable_plugin=(int)pov[5];
248 if (variable_index<0){
249 debug()<<
"\33[33m[HyodaIceT::sxyzi] Fetched negative variable_index!\33[m";
252 if (variable_plugin<0 || variable_plugin>2){
253 debug()<<
"\33[33m[HyodaIceT::sxyzi] Fetched uncompatible variable_plugin!\33[m";
259 VariableCollection variables = m_sub_domain->variableMng()->usedVariables();
260 debug()<<
"\33[33m[HyodaIceT::sxyzi] Looking for variable #"<<variable_index<<
"\33[m";
261 for(VariableCollection::Enumerator ivar(variables); ++ivar;){
263 if (m_variable->nbReference()==0)
continue;
264 if (m_variable->itemKind()!=IK_Node &&
265 m_variable->itemKind()!=IK_Cell &&
266 m_variable->itemKind()!=IK_Face &&
267 m_variable->itemKind()!=IK_Particle)
continue;
268 if (m_variable->itemKind()!=IK_Particle && (!m_variable->hasTag(
"PostProcessing")))
continue;
270 if (m_variable->dataType()!=DT_Real)
continue;
271 if (i==variable_index)
break;
272 if (i>variable_index)
273 fatal()<<
"\33[33m[HyodaIceT::sxyzi] Could not find variable to draw (variable_index="<<variable_index<<
", i="<<i<<
")!\33[m\n";
276 debug()<<
"\33[33m[HyodaIceT::sxyzi] " << m_variable->name()<<
"\33[m";
283int HyodaIceT::renderSize(
void){
284 return m_screen_width*m_screen_height*4*
sizeof(GLubyte);
291HyodaIceT::~HyodaIceT(){
292 free(m_image_buffer);
295 debug()<<
"\33[33m~HyodaIceT\33[m";
296 icetDestroyContext(icetContext);
297 OSMesaDestroyContext(osMesaContext);
305void HyodaIceT::render(
void){
306 debug()<<
"\33[33m[HyodaIceT] render\33[m";
307 icetGLDrawCallback(drawGLCallback);
311 platform::enableFloatingException(
false);
312 IceTImage image=icetGLDrawFrame();
313 platform::enableFloatingException(
true);
317 m_sub_domain->parallelMng()->barrier();
322 unsigned char* imgAddress=icetImageGetColorub(image);
325 if (!platform::getEnvironmentVariable(
"ARCANE_HYODA_MESH_PPM").null()){
327 if (29!=snprintf(filename,3883,
"/tmp/HyODA_Msh_%04d.ppm", m_sub_domain->commonVariables().globalIteration()))
329 debug()<<
"\33[33m[HyodaIceT::render] \33[33mARCANE_HYODA_MESH_PPM\33[m "
330 << icetImageGetWidth(image) <<
"x" << icetImageGetHeight(image)
331 <<
" image " << filename;
332 ppmWrite(filename, imgAddress,(
int)m_screen_width, (
int)m_screen_height);
335 debug()<<
"\33[33m[HyodaIceT::render] sending header packet for image!\33[m";
336 char icePacketHeader[8];
338 *(
unsigned int*)&icePacketHeader[0]=0xcbce69bcul;
340 *(
unsigned int*)&icePacketHeader[4]=8;
341 m_tcp->send(icePacketHeader,8);
342 m_tcp->waitForAcknowledgment();
343 debug()<<
"\33[33m[HyodaIceT::render] sending image packet!, renderSize="<<renderSize()<<
"\33[m";
344 m_tcp->send((
void*)imgAddress, renderSize());
345 m_tcp->waitForAcknowledgment();
346 debug()<<
"\33[33m[HyodaIceT::render] Waiting for POV answer!\33[m";
347 m_tcp->recvPov(m_pov_sxyzip);
350 m_sub_domain->parallelMng()->barrier();
353 UniqueArray<Real> pov_to_broadcast(0);
354 pov_to_broadcast.add(m_pov_sxyzip[0]);
355 pov_to_broadcast.add(m_pov_sxyzip[1]);
356 pov_to_broadcast.add(m_pov_sxyzip[2]);
357 pov_to_broadcast.add(m_pov_sxyzip[3]);
358 pov_to_broadcast.add(m_pov_sxyzip[4]);
359 pov_to_broadcast.add(m_pov_sxyzip[5]);
360 debug()<<
"\33[33m[Hyoda::hook] broadcasting pov...\33[m";
361 m_sub_domain->parallelMng()->broadcast(pov_to_broadcast.view(),0);
362 m_pov_sxyzip[0]=pov_to_broadcast[0];
363 m_pov_sxyzip[1]=pov_to_broadcast[1];
364 m_pov_sxyzip[2]=pov_to_broadcast[2];
365 m_pov_sxyzip[3]=pov_to_broadcast[3];
366 m_pov_sxyzip[4]=pov_to_broadcast[4];
367 m_pov_sxyzip[5]=pov_to_broadcast[5];
368 sxyzip(m_pov_sxyzip);
369 debug()<<
"\33[33m[Hyoda::hook] pov done\33[m";
370 debug()<<
"\33[33m[HyodaIceT::render] sxyzip:"
371 <<
"scale=" << m_pov_sxyzip[0]
372 <<
", x=" << m_pov_sxyzip[1]
373 <<
", y=" << m_pov_sxyzip[2]
374 <<
", z=" << m_pov_sxyzip[3]
375 <<
", i=" << m_pov_sxyzip[4]
376 <<
", p=" << m_pov_sxyzip[5]
384void HyodaIceT::initGL(
void){
385 debug()<<
"\33[33m[HyodaIceT] initGL in\33[m";
387 glViewport(0, 0, m_screen_width,m_screen_height);
389 glEnable(GL_DEPTH_TEST);
390 glEnable(GL_MULTISAMPLE);
391 glEnable(GL_POINT_SMOOTH);
396 glDepthFunc(GL_LESS);
397 glShadeModel(GL_SMOOTH);
398 glShadeModel(GL_FLAT);
399 glLineStipple(1, 0x0101);
400 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
402 glColor3f(0.0f, 0.0f, 0.0f);
403 glClearColor(0.0, 0.0, 0.0, 0.0);
404 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
405 debug()<<
"\33[33m[HyodaIceT] initGL out\33[m";
413void HyodaIceT::drawGL(
void){
414 debug()<<
"\33[33m[HyodaIceT] drawGL\33[m";
416 glShadeModel(GL_SMOOTH);
417 glMatrixMode(GL_PROJECTION);
419 Real length=lrbtnf[1]-lrbtnf[0];
420 Real height=lrbtnf[3]-lrbtnf[2];
422 glOrtho(lrbtnf[0]-length/4., lrbtnf[1]+length/4., lrbtnf[2]-height/4., lrbtnf[3]+height/4., lrbtnf[4], lrbtnf[5]);
426 glRotatef(rot_x, 1.0f, 0.0f, 0.0f);
427 glRotatef(rot_y, 0.0f, 1.0f, 0.0f);
428 glRotatef(rot_z, 0.0f, 0.0f, 1.0f);
429 glScalef(scale, scale, scale);
430 glMatrixMode(GL_MODELVIEW);
431 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
443void HyodaIceT::drawArcaneMesh(
void){
451 debug()<<
"\33[33m[HyodaIceT] drawArcaneMesh\33[m";
460void HyodaIceT::iceColorMinMax(
Real &min,
Real &max){
461 String item_family_name(m_variable->itemFamilyName()==NULL?
462 "particles":m_variable->itemFamilyName());
464 m_variable->name(),item_family_name),
465 m_variable->itemKind());
468 min = math::min(min,val);
469 max = math::max(max,val);
471 min=m_sub_domain->parallelMng()->reduce(Parallel::ReduceMin, min);
472 max=m_sub_domain->parallelMng()->reduce(Parallel::ReduceMax, max);
473 debug()<<
"\33[33m[iceColorMinMax] min="<<
min<<
", max="<<
max<<
"\33[m";
480void HyodaIceT::drawArcPolygons(
void){
484 String item_family_name(m_variable->itemFamilyName()==NULL?
485 "particles":m_variable->itemFamilyName());
488 m_variable->name(),item_family_name),
489 m_variable->itemKind());
492 iceColorMinMax(min,max);
493 if (m_sub_domain->defaultMesh()->dimension()==2){
494 debug()<<
"\33[33m[drawArcPolygons] 2D\33[m";
496 if (variable_plugin!=0){
497 debug()<<
"\33[33m[drawArcPolygons] variable_plugin="<<variable_plugin<<
"\33[m";
498 m_hyoda_mix->xLine2Cell(variable_plugin, m_variable, min, max);
504 debug()<<
"\33[33m[drawArcPolygons] variable_plugin="<<variable_plugin<<
"\33[m";
505 if ((m_variable->itemKind()==IK_Cell)||(m_variable->itemKind()==IK_Node)){
506 debug()<<
"\33[33m[drawArcPolygons] m_variable->name()="<<m_variable->name()<<
"\33[m";
507 debug()<<
"\33[33m[drawArcPolygons] m_variable->itemKind()="<<m_variable->itemKind()<<
"\33[m";
510 if (m_variable->itemKind()==IK_Cell) setColor(min,max,var[cell],rgb);
512 if (m_variable->itemKind()==IK_Node) setColor(min,max,var[node],rgb);
513 glColor3d(rgb[0], rgb[1], rgb[2]);
514 glVertex2d(nCoords[node].x, nCoords[node].y);
523 if (m_variable->itemKind()==IK_Face){
524 debug()<<
"\33[33m[drawArcPolygons] IK_Face!\33[m";
527 setColor(min,max,var[face],rgb);
528 glColor3d(rgb[0], rgb[1], rgb[2]);
530 glVertex2d(nCoords[node].x, nCoords[node].y);
540 if (m_sub_domain->defaultMesh()->dimension()==3){
541 debug()<<
"\33[33m[drawArcPolygons] 3D\33[m";
542 if (m_variable->itemKind()==IK_Cell){
544 if (!face->isOwn())
continue;
546 setColor(min,max,var[face->cell(0)],rgb);
547 glColor3d(rgb[0], rgb[1], rgb[2]);
549 glVertex3d(nCoords[node].x,
557 if (m_variable->itemKind()==IK_Particle){
559 ENUMERATE_PARTICLE(particle, m_sub_domain->defaultMesh()->findItemFamily(
"particles",
true)->allItems()){
560 if (!particle->cell().isOwn())
continue;
562 setColor(min,max,var[particle],rgb);
563 glColor3d(rgb[0], rgb[1], rgb[2]);
564 glVertex3d(m_particle_r[particle].x,m_particle_r[particle].y,m_particle_r[particle].z);
585void HyodaIceT::drawArcPolygonsWithoutVariable(
void){
589 glColor3d(0.0, 0.0, 1.0);
591 glVertex3d(nCoords[node].x,
603void HyodaIceT::drawArcPoints(
const VariableItemReal3 &nodes_coords,
604 VariableItemReal &var,
605 double min,
double max){
617 #warning Only cell Variables for drawArcPoints
618 setColor(min,max,var[cell],rgb);
620 glColor3d(rgb[0], rgb[1], rgb[2]);
621 glVertex3d(nodes_coords[node].x,
622 nodes_coords[node].y,
623 nodes_coords[node].z);
633void HyodaIceT::drawArcLines(
const VariableItemReal3 &nodes_coords,
638 glColor3f(0.0f, 0.0f, 0.0f);
640 for(Integer i=0,mx=face->nodes().size()-1;i<mx;++i){
641 glVertex3d(nodes_coords[face->node(i)].x,
642 nodes_coords[face->node(i)].y,
643 nodes_coords[face->node(i)].z);
644 glVertex3d(nodes_coords[face->node(i+1)].x,
645 nodes_coords[face->node(i+1)].y,
646 nodes_coords[face->node(i+1)].z);
648 glVertex3d(nodes_coords[face->node(0)].x,
649 nodes_coords[face->node(0)].y,
650 nodes_coords[face->node(0)].z);
651 glVertex3d(nodes_coords[face->node(face->nodes().size()-1)].x,
652 nodes_coords[face->node(face->nodes().size()-1)].y,
653 nodes_coords[face->node(face->nodes().size()-1)].z);
663setColor(
double min,
double max,
double v, Real3 &rgb)
665 ARCANE_ASSERT(min<=max,(
"setColor min<=max"));
671 ARCANE_ASSERT(mid!=0.,(
"setColor mid!=0."));
672 rgb.x=rgb.y=rgb.z=1.0;
675 if (v<(min+0.25*mid)){
677 rgb.y=4.*(v-
min)/mid;
678 }
else if (v<(min+0.5*mid)){
680 rgb.z=1.+4*(
min+0.25*mid-v)/mid;
681 }
else if (v<(min+0.75*mid)){
682 rgb.x=4*(v-
min-0.5*mid)/mid;
685 rgb.y=1.+4*(
min+0.75*mid-v)/mid;
694void HyodaIceT::checkIceTError(
void){
695#define CASE_ERROR(ename) case ename: debug() << "\33[33m## IceT status = " << #ename << "\33[m"; break;
696 switch (icetGetError()) {
697 case(ICET_NO_ERROR):
break;
698 CASE_ERROR(ICET_SANITY_CHECK_FAIL);
699 CASE_ERROR(ICET_INVALID_ENUM);
700 CASE_ERROR(ICET_BAD_CAST);
701 CASE_ERROR(ICET_OUT_OF_MEMORY);
702 CASE_ERROR(ICET_INVALID_OPERATION);
703 CASE_ERROR(ICET_INVALID_VALUE);
704 default:debug()<<
"\33[33m## UNKNOWN ICET ERROR CODE!!!!!\33[m";
713void HyodaIceT::checkOglError(
void){
714#define CASE_ERROR(ename) case ename: debug() << "\33[33m## OpenGL status = " << #ename << "\33[m"; break;
715 switch (glGetError()) {
716 case(GL_NO_ERROR):
break;
717 CASE_ERROR(GL_INVALID_ENUM);
718 CASE_ERROR(GL_INVALID_VALUE);
719 CASE_ERROR(GL_INVALID_OPERATION);
720 CASE_ERROR(GL_STACK_OVERFLOW);
721 CASE_ERROR(GL_STACK_UNDERFLOW);
722 CASE_ERROR(GL_OUT_OF_MEMORY);
723#ifdef GL_TABLE_TOO_LARGE
724 CASE_ERROR(GL_TABLE_TOO_LARGE);
726 default:debug()<<
"\33[33m## UNKNOWN GL ERROR CODE!!!!!\33[m";
Fichier de configuration d'Arcane.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
ARCCORE_HOST_DEVICE Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
MeshVariableScalarRefT< Particle, Real3 > VariableParticleReal3
Grandeur particulaire de type coordonnées.
ItemVariableScalarRefT< Real > VariableItemReal
Grandeur de type réel.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
ItemVariableScalarRefT< Real3 > VariableItemReal3
Grandeur de type coordonn?es 3D.