DATAKIT SDK  V2026.4
LoadBodiesIntoSession.cpp File Reference

Functions

void ActivatePsMemory (bool inActivate)
 
void ActivatePsSession (bool inActivate)
 
void ActivatePsTraverse (bool inActivate)
 
void EnumerateBodiesInSession ()
 
bool IsPsMemoryActivated ()
 
bool IsPsSessionActivated ()
 
bool IsPsTraverseActivated ()
 
void LoadBodiesIntoPsSession (const Dtk_string &inXtFile)
 
void LoadBodiesIntoPsSessionFromStream (const Dtk_tab< char > &inStream)
 
static PK_ERROR_code_t PsErrorHandler (PK_ERROR_sf_t *error_sf)
 
void ReceiveBodiesIntoCurrentPsSession (const Dtk_string &inXtFile)
 
void ReceiveBodiesIntoCurrentPsSessionFromStream (const Dtk_tab< char > &inStream)
 
static void ReceiveBodyFromTempFile (const char *inData, Dtk_Size_t inDataSize, const string &inIndent)
 
static void SetPSchema ()
 
static void StartPsSession ()
 
void StartSharedPsSession ()
 
static void StopPsSession ()
 
void StopSharedPsSession ()
 
static void TraverseNodeBodiesFromStream (Dtk_NodePtr inNode, int inDepth)
 

Variables

static bool s_psMemoryActivated = false
 
static bool s_psSessionActivated = false
 
static bool s_psTraverseActivated = false
 

Function Documentation

◆ ActivatePsMemory()

void ActivatePsMemory ( bool  inActivate)
44 { s_psMemoryActivated = inActivate; }

◆ ActivatePsSession()

void ActivatePsSession ( bool  inActivate)
43 { s_psSessionActivated = inActivate; }

◆ ActivatePsTraverse()

void ActivatePsTraverse ( bool  inActivate)
45 { s_psTraverseActivated = inActivate; }

◆ EnumerateBodiesInSession()

void EnumerateBodiesInSession ( )
148 {
149  PK_PARTITION_t partition = 0;
150  PK_SESSION_ask_curr_partition( &partition );
151 
152  int nBodies = 0;
153  PK_BODY_t* bodies = nullptr;
154  PK_PARTITION_ask_bodies( partition, &nBodies, &bodies );
155  cout << "Bodies in active partition: " << nBodies << endl;
156 
157  for( int i = 0; i < nBodies; ++i )
158  {
159  PK_BODY_t body = bodies[ i ];
160 
161  PK_BODY_type_t bodyType = 0;
162  PK_BODY_ask_type( body, &bodyType );
163 
164  int nFaces = 0;
165  PK_FACE_t* faces = nullptr;
166  PK_ERROR_code_t fErr = PK_BODY_ask_faces( body, &nFaces, &faces );
167 
168  const char* typeName = "unknown";
169  if ( bodyType == PK_BODY_type_solid_c ) typeName = "solid";
170  else if( bodyType == PK_BODY_type_sheet_c ) typeName = "sheet";
171  else if( bodyType == PK_BODY_type_wire_c ) typeName = "wire";
172  else if( bodyType == PK_BODY_type_acorn_c ) typeName = "acorn";
173  else if( bodyType == PK_BODY_type_general_c ) typeName = "general";
174 
175  if( fErr == PK_ERROR_none )
176  {
177  cout << " Body[" << i << "] tag=" << body
178  << " type=" << typeName
179  << " faces=" << nFaces << endl;
180  if( faces ) PK_MEMORY_free( faces );
181  }
182  else
183  {
184  cout << " Body[" << i << "] tag=" << body
185  << " type=" << typeName
186  << " PK_BODY_ask_faces error=" << fErr << endl;
187  }
188  }
189 
190  if( bodies ) PK_MEMORY_free( bodies );
191 }

◆ IsPsMemoryActivated()

bool IsPsMemoryActivated ( )
48 { return s_psMemoryActivated; }

◆ IsPsSessionActivated()

bool IsPsSessionActivated ( )
47 { return s_psSessionActivated; }

◆ IsPsTraverseActivated()

bool IsPsTraverseActivated ( )
49 { return s_psTraverseActivated; }

◆ LoadBodiesIntoPsSession()

void LoadBodiesIntoPsSession ( const Dtk_string &  inXtFile)
199 {
200  cout << "\n--- Parasolid session: loading \""
201  << inXtFile.c_str() << "\" from disk ---" << endl;
202 
203  SetPSchema();
204  StartPsSession();
205 
206  PK_PART_receive_o_t recvOpts;
207  PK_PART_receive_o_m( recvOpts );
208 
209  int nParts = 0;
210  PK_PART_t* parts = nullptr;
211  PK_ERROR_code_t pkErr = PK_PART_receive(
212  inXtFile.c_str(), &recvOpts, &nParts, &parts );
213 
214  if( pkErr != PK_ERROR_none )
215  {
216  cout << "PK_PART_receive failed, error code: " << pkErr << endl;
217  StopPsSession();
218  return;
219  }
220  cout << "PK_PART_receive: " << nParts << " part(s) received." << endl;
221 
223 
224  if( parts ) PK_MEMORY_free( parts );
225 
226  StopPsSession();
227  cout << "--- Parasolid session closed ---" << endl;
228 }

◆ LoadBodiesIntoPsSessionFromStream()

void LoadBodiesIntoPsSessionFromStream ( const Dtk_tab< char > &  inStream)
237 {
238  if( inStream.size() == 0 )
239  {
240  cout << "Warning: in-memory stream is empty, nothing to load." << endl;
241  return;
242  }
243 
244  cout << "\n--- Parasolid session: loading "
245  << inStream.size() << " bytes from in-memory stream ---" << endl;
246 
247  SetPSchema();
248  StartPsSession();
249 
250  // Map the Dtk_tab<char> buffer to a single PK_MEMORY_block_t.
251  PK_MEMORY_block_t block;
252  block.next = nullptr;
253  block.n_bytes = static_cast<size_t>( inStream.size() );
254  block.bytes = &inStream[ 0 ];
255 
256  PK_PART_receive_o_t recvOpts;
257  PK_PART_receive_o_m( recvOpts );
258 
259  int nParts = 0;
260  PK_PART_t* parts = nullptr;
261  PK_ERROR_code_t pkErr = PK_PART_receive_b( block, &recvOpts, &nParts, &parts );
262 
263  if( pkErr != PK_ERROR_none )
264  {
265  cout << "PK_PART_receive_b failed, error code: " << pkErr << endl;
266  StopPsSession();
267  return;
268  }
269  cout << "PK_PART_receive_b: " << nParts << " part(s) received." << endl;
270 
272 
273  if( parts ) PK_MEMORY_free( parts );
274 
275  StopPsSession();
276  cout << "--- Parasolid session closed ---" << endl;
277 }

◆ PsErrorHandler()

static PK_ERROR_code_t PsErrorHandler ( PK_ERROR_sf_t *  error_sf)
static
55 {
56  return error_sf->code;
57 }

◆ ReceiveBodiesIntoCurrentPsSession()

void ReceiveBodiesIntoCurrentPsSession ( const Dtk_string &  inXtFile)
291 {
292  cout << "\n--- Receiving \""
293  << inXtFile.c_str()
294  << "\" into existing Parasolid session ---" << endl;
295 
296  PK_PART_receive_o_t recvOpts;
297  PK_PART_receive_o_m( recvOpts );
298 
299  int nParts = 0;
300  PK_PART_t* parts = nullptr;
301  PK_ERROR_code_t pkErr = PK_PART_receive(
302  inXtFile.c_str(), &recvOpts, &nParts, &parts );
303 
304  if( pkErr != PK_ERROR_none )
305  {
306  cout << "PK_PART_receive failed, error code: " << pkErr << endl;
307  return;
308  }
309  cout << "PK_PART_receive: " << nParts << " part(s) received." << endl;
310 
311  if( parts ) PK_MEMORY_free( parts );
312 }

◆ ReceiveBodiesIntoCurrentPsSessionFromStream()

void ReceiveBodiesIntoCurrentPsSessionFromStream ( const Dtk_tab< char > &  inStream)
320 {
321  if( inStream.size() == 0 )
322  {
323  cout << "Warning: in-memory stream is empty, nothing to receive." << endl;
324  return;
325  }
326 
327  cout << "\n--- Receiving "
328  << inStream.size()
329  << " bytes from in-memory stream into existing Parasolid session ---" << endl;
330 
331  PK_MEMORY_block_t block;
332  block.next = nullptr;
333  block.n_bytes = static_cast<size_t>( inStream.size() );
334  block.bytes = &inStream[ 0 ];
335 
336  PK_PART_receive_o_t recvOpts;
337  PK_PART_receive_o_m( recvOpts );
338 
339  int nParts = 0;
340  PK_PART_t* parts = nullptr;
341  PK_ERROR_code_t pkErr = PK_PART_receive_b( block, &recvOpts, &nParts, &parts );
342 
343  if( pkErr != PK_ERROR_none )
344  {
345  cout << "PK_PART_receive_b failed, error code: " << pkErr << endl;
346  return;
347  }
348  cout << "PK_PART_receive_b: " << nParts << " part(s) received." << endl;
349 
350  if( parts ) PK_MEMORY_free( parts );
351 }

◆ ReceiveBodyFromTempFile()

static void ReceiveBodyFromTempFile ( const char *  inData,
Dtk_Size_t  inDataSize,
const string &  inIndent 
)
static
368 {
369  Dtk_string tempFile = Dtk_API::GetAPI()->GetWorkingDir();
370  tempFile += L"dtk_ps_traverse.x_b";
371  tempFile.FixPathSeparator();
372 
373  FILE* fp = tempFile.OpenFile( DTK_WB );
374  if( !fp )
375  {
376  cout << inIndent << " Error: cannot write temp file "
377  << tempFile.c_str() << endl;
378  return;
379  }
380  fwrite( inData, sizeof(char), static_cast<size_t>( inDataSize ), fp );
381  fclose( fp );
382 
383  // Key string for PK_PART_receive: path without extension.
384  Dtk_string realName = tempFile.drive() + tempFile.path() + tempFile.filename();
385 
386  PK_PART_receive_o_t partOpts;
387  PK_PART_receive_o_m( partOpts );
388  partOpts.transmit_format = PK_transmit_format_binary_c;
389 
390  PK_PARTITION_receive_o_t partitionOpts;
391  PK_PARTITION_receive_o_m( partitionOpts );
392  partitionOpts.transmit_format = PK_transmit_format_binary_c;
393 
394  int nParts = 0;
395  PK_PART_t* parts = nullptr;
396 
397  PK_ERROR_code_t pkErr = PK_PART_receive(
398  realName.c_str(), &partOpts, &nParts, &parts );
399 
400  if( pkErr == PK_ERROR_corrupt_file )
401  {
402  // Fallback: file may be a partition (assembly) rather than a single part.
403  PK_PARTITION_t partition = 0;
404  pkErr = PK_PARTITION_receive(
405  realName.c_str(), &partitionOpts, &partition );
406  if( pkErr == PK_ERROR_none && partition > 0 )
407  pkErr = PK_PARTITION_ask_bodies( partition, &nParts,
408  (PK_BODY_t**)&parts );
409  }
410 
411  tempFile.unlink();
412 
413  if( pkErr == PK_ERROR_none )
414  cout << inIndent << " -> " << nParts
415  << " body/bodies added to session." << endl;
416  else
417  cout << inIndent << " -> PK_PART_receive error: " << pkErr << endl;
418 
419  if( parts ) PK_MEMORY_free( parts );
420 }

◆ SetPSchema()

static void SetPSchema ( )
static
65 {
66  Dtk_string schemaDir = "./Schema";
67 #ifndef Linux
68  char fullPath[ _MAX_PATH ];
69  if( _fullpath( fullPath, "./Schema", _MAX_PATH ) != nullptr )
70  schemaDir = fullPath;
71  // Buffer must stay alive for the process lifetime.
72  static wchar_t schEnvW[ 2048 ];
73  swprintf( schEnvW, 2047, L"P_SCHEMA=%s", schemaDir.w_str() );
74  _wputenv( schEnvW );
75 #else
76  static char schEnvA[ 2048 ];
77  snprintf( schEnvA, sizeof(schEnvA), "P_SCHEMA=%s", schemaDir.c_str() );
78  putenv( schEnvA );
79 #endif
80 }

◆ StartPsSession()

static void StartPsSession ( )
static
88 {
89  PK_SESSION_frustrum_t frustrum;
90  PK_SESSION_frustrum_o_m( frustrum );
91  frustrum.fstart = FSTART;
92  frustrum.fabort = FABORT;
93  frustrum.fstop = FSTOP;
94  frustrum.fmallo = FMALLO;
95  frustrum.fmfree = FMFREE;
96  frustrum.ffoprd = FFOPRD;
97  frustrum.ffopwr = FFOPWR;
98  frustrum.ffclos = FFCLOS;
99  frustrum.ffread = FFREAD;
100  frustrum.ffwrit = FFWRIT;
101  frustrum.goopsg = GOOPSG;
102  frustrum.goclsg = GOCLSG;
103  frustrum.gosgmt = GOSGMT;
104  PK_SESSION_register_frustrum( &frustrum );
105 
106  PK_SESSION_start_o_t sessionOpts;
107  PK_SESSION_start_o_m( sessionOpts );
108  sessionOpts.user_field = 16;
109  PK_SESSION_start( &sessionOpts );
110 
111  PK_ERROR_frustrum_t errFrustrum;
112  errFrustrum.handler_fn = PsErrorHandler;
113  PK_ERROR_register_callbacks( errFrustrum );
114 
115  PK_SESSION_set_journalling( PK_LOGICAL_true );
116  PK_SESSION_set_check_self_int( PK_LOGICAL_false );
117  PK_SESSION_set_check_continuity( PK_LOGICAL_false );
118 
119  PK_SESSION_kernel_version_t ver;
120  if( PK_SESSION_ask_kernel_version( &ver ) == PK_ERROR_none )
121  cout << "PsKernel version: "
122  << ver.major_revision << "."
123  << ver.minor_revision << "."
124  << ver.build_number << endl;
125 }

◆ StartSharedPsSession()

void StartSharedPsSession ( )
140 { SetPSchema(); StartPsSession(); }

◆ StopPsSession()

static void StopPsSession ( )
static
131 {
132  PK_SESSION_stop();
133 }

◆ StopSharedPsSession()

void StopSharedPsSession ( )
141 { StopPsSession(); }

◆ TraverseNodeBodiesFromStream()

static void TraverseNodeBodiesFromStream ( Dtk_NodePtr  inNode,
int  inDepth 
)
static
429 {
430  if( inNode.IsNULL() ) return;
431 
432  int blanked = inNode->GetInfos()->GetBlankedStatus();
433  if( blanked == 1 )
434  {
435  Dtk_Size_t n = inNode->GetNumChildren();
436  for( Dtk_Size_t i = 0; i < n; ++i )
437  TraverseNodeBodiesFromStream( inNode->GetChild(i), inDepth );
438  return;
439  }
440 
441  string indent( static_cast<size_t>( inDepth ) * 2, ' ' );
442  Dtk_Node::FullType nodeType = inNode->GetNodeFullType();
443 
444  if( nodeType.PrimaryType() == Dtk_Node::BodyType
445  && inNode->GetInfos()->GetInfiniteGeometryFlag() == 0
446  && blanked == 0 )
447  {
448  Dtk_BodyPtr body = inNode->GetDtk_BodyPtr();
449  if( body.IsNotNULL() )
450  {
451  Dtk_string name;
452  if( body->info().IsNotNULL() ) name = body->info()->GetName();
453 
454  Dtk_Size_t numStreams = body->GetNumStream();
455  bool found = false;
456  for( Dtk_Size_t s = 0; s < numStreams; ++s )
457  {
458  Dtk_StreamPtr stream = body->GetStream( s );
459  if( stream.IsNotNULL()
460  && stream->GetStreamType() == Dtk_Stream::DTK_STREAM_X_B )
461  {
462  const char* data = stream->GetBinaryContent();
463  const Dtk_Size_t dataSize = stream->GetBinaryContentSize();
464 
465  cout << indent << "[Body]";
466  if( name.len() > 0 ) cout << " \"" << name.c_str() << "\"";
467  cout << " stream=" << dataSize << " B" << endl;
468 
469  ReceiveBodyFromTempFile( data, dataSize, indent );
470  found = true;
471  break;
472  }
473  }
474  if( !found )
475  {
476  cout << indent << "[Body]";
477  if( name.len() > 0 ) cout << " \"" << name.c_str() << "\"";
478  cout << " (no Parasolid stream, skipped)" << endl;
479  }
480  }
481  }
482 
483  Dtk_Size_t n = inNode->GetNumChildren();
484  for( Dtk_Size_t i = 0; i < n; ++i )
485  TraverseNodeBodiesFromStream( inNode->GetChild(i), inDepth );
486 }

Variable Documentation

◆ s_psMemoryActivated

bool s_psMemoryActivated = false
static

◆ s_psSessionActivated

bool s_psSessionActivated = false
static

◆ s_psTraverseActivated

bool s_psTraverseActivated = false
static
Dtk_SmartPtr::IsNotNULL
Dtk_bool IsNotNULL() const
Definition: util_ptr_dtk.hpp:119
Dtk_Node::FullType::PrimaryType
NodeDataTypeEnum PrimaryType() const
Definition: dtk_maindoc.hpp:285
Dtk_string
This is a high level string class.
Definition: dtk_string.hpp:53
Dtk_Size_t
size_t Dtk_Size_t
Definition: define.h:711
Dtk_string::unlink
int unlink() const
File Utility : Delete a file.
Dtk_string::path
Dtk_string path() const
File Utility : Retrieves the path in Dtk_string form.
Dtk_Node::BodyType
@ BodyType
Definition: dtk_maindoc.hpp:252
Dtk_string::OpenFile
FILE * OpenFile(const Dtk_string &inRights) const
File Utility : Open a file with the given rights.
PsErrorHandler
static PK_ERROR_code_t PsErrorHandler(PK_ERROR_sf_t *error_sf)
Definition: LoadBodiesIntoSession.cpp:54
Dtk_API::GetWorkingDir
const Dtk_string & GetWorkingDir() const
EnumerateBodiesInSession
void EnumerateBodiesInSession()
Definition: LoadBodiesIntoSession.cpp:147
DTK_WB
#define DTK_WB
Definition: dtk_string.hpp:40
Dtk_API::GetAPI
static Dtk_API * GetAPI()
Get DATAKIT API.
Dtk_string::filename
Dtk_string filename() const
File Utility : Retrieves the filename in Dtk_string form.
s_psMemoryActivated
static bool s_psMemoryActivated
Definition: LoadBodiesIntoSession.cpp:40
Dtk_Node::FullType
This is the Node FullType Class The Dtk_Node::FullType object is used to retrieve the full informatio...
Definition: dtk_maindoc.hpp:273
StopPsSession
static void StopPsSession()
Definition: LoadBodiesIntoSession.cpp:130
Dtk_SmartPtr::IsNULL
Dtk_bool IsNULL() const
Definition: util_ptr_dtk.hpp:118
ReceiveBodyFromTempFile
static void ReceiveBodyFromTempFile(const char *inData, Dtk_Size_t inDataSize, const string &inIndent)
Definition: LoadBodiesIntoSession.cpp:365
Dtk_SmartPtr
Definition: util_ptr_dtk.hpp:37
Dtk_string::c_str
const char * c_str() const
Retrieve the ASCII conversion string.
Dtk_Stream::DTK_STREAM_X_B
@ DTK_STREAM_X_B
Definition: dtk_stream.hpp:22
Dtk_string::FixPathSeparator
void FixPathSeparator()
File Utility : Fixes path separator consistency. It lets you replace the '\' or '/' by the OS needed ...
TraverseNodeBodiesFromStream
static void TraverseNodeBodiesFromStream(Dtk_NodePtr inNode, int inDepth)
Definition: LoadBodiesIntoSession.cpp:428
Dtk_string::drive
Dtk_string drive() const
File Utility : Retrieves the drive in Dtk_string form.
SetPSchema
static void SetPSchema()
Definition: LoadBodiesIntoSession.cpp:64
Dtk_tab::size
Dtk_Size_t size() const
Returns the size of the array.
Definition: util_stl_dtk.hpp:503
s_psTraverseActivated
static bool s_psTraverseActivated
Definition: LoadBodiesIntoSession.cpp:41
Dtk_string::len
int len() const
Retrieve the length of the Dtk_string.
StartPsSession
static void StartPsSession()
Definition: LoadBodiesIntoSession.cpp:87
s_psSessionActivated
static bool s_psSessionActivated
Definition: LoadBodiesIntoSession.cpp:39