PatriciaTrieNode<S,T>* PatriciaTrie<S,T>::find_bitindex_node (PatriciaTrieNode<S,T>* root, int bitindex) { // // is the head-pseudo-node requested? // if (bitindex == -1) return head; // // check all the normal nodes // NODE_LIST nodes = GetNodeList (root); NODE_LIST_ITERATOR i = nodes.begin (); NODE_LIST_ITERATOR iend = nodes.end (); for ( ; i != iend; i++) { PatriciaTrieNode<S,T>* node = *i; if (node->bit_index == bitindex) return node; } return NULL; }
bool X3D_MODEL_PARSER::Load( const wxString& aFilename ) { wxLogTrace( traceX3DParser, wxT( "Loading: %s" ), GetChars( aFilename ) ); wxXmlDocument doc; if( !doc.Load( aFilename ) ) { wxLogTrace( traceX3DParser, wxT( "Error while parsing file: %s" ), GetChars( aFilename ) ); return false; } if( doc.GetRoot()->GetName() != wxT( "X3D" ) ) { wxLogTrace( traceX3DParser, wxT( "Filetype is not X3D: %s" ), GetChars( aFilename ) ); return false; } // Switch the locale to standard C (needed to print floating point numbers) LOCALE_IO toggle; childs.clear(); // Shapes are inside of Transform nodes // Transform node contains information about // transition, scale and rotation of the shape NODE_LIST transforms; GetChildsByName( doc.GetRoot(), wxT( "Transform" ), transforms ); for( NODE_LIST::iterator node_it = transforms.begin(); node_it != transforms.end(); node_it++ ) { m_model.reset( new S3D_MESH() ); childs.push_back( m_model ); wxXmlNode* node = *node_it; wxXmlAttribute* prop = node->GetAttributes(); wxLogTrace( traceX3DParser, wxT( "Transform: %s %s" ), prop->GetName(), prop->GetValue() ); readTransform( node ); } return true; }
void X3D_MODEL_PARSER::readTransform( wxXmlNode* aTransformNode ) { NODE_LIST childnodes; GetChildsByName( aTransformNode, wxT( "Material" ), childnodes ); for( NODE_LIST::iterator node = childnodes.begin(); node != childnodes.end(); node++ ) { readMaterial( *node ); } childnodes.clear(); PROPERTY_MAP properties; GetNodeProperties( aTransformNode, properties ); GetChildsByName( aTransformNode, wxT( "IndexedFaceSet" ), childnodes ); for( NODE_LIST::iterator node = childnodes.begin(); node != childnodes.end(); node++ ) { readIndexedFaceSet( *node, properties ); } childnodes.clear(); }
typename PatriciaTrie<S,T>::NODE_LIST PatriciaTrie<S,T>::GetNodeList (PatriciaTrieNode<S,T>* root) { NODE_LIST retNodes; NODE_LIST newItemsLeft, newItemsRight; PatriciaTrieNode<S,T>* startNode = (root == NULL ? head : root); // // insert the current node if it is not the root node // if (startNode->bit_index >= 0) retNodes.insert (retNodes.end (), startNode); // // walk down left wing // if (startNode->left != NULL && startNode->left->bit_index > startNode->bit_index) newItemsLeft = GetNodeList (startNode->left); retNodes.insert (retNodes.end(), newItemsLeft.begin(), newItemsLeft.end()); // // walk down right wing // if (startNode->right != NULL && startNode->right->bit_index > startNode->bit_index) newItemsRight = GetNodeList (startNode->right); retNodes.insert (retNodes.end(), newItemsRight.begin(), newItemsRight.end()); return retNodes; }
/* Steps: * 1. Read transform data * 2. Read vertex triplets * 3. Read coordinate indexes * 4. Apply geometry to Master object */ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode, PROPERTY_MAP& aTransformProps ) { /* Step 1: Read transform data * --------------------------- */ S3D_VERTEX translation; parseDoubleTriplet( aTransformProps[ wxT( "translation" ) ], translation ); S3D_VERTEX scale; parseDoubleTriplet( aTransformProps[ wxT( "scale" ) ], scale ); S3D_VERTEX rotation; double angle = 0.0; wxStringTokenizer tokens( aTransformProps[ wxT( "rotation" ) ] ); double x = 0.0, y = 0.0, z = 0.0; if( !( tokens.GetNextToken().ToDouble( &x ) && tokens.GetNextToken().ToDouble( &y ) && tokens.GetNextToken().ToDouble( &z ) && tokens.GetNextToken().ToDouble( &angle ) ) ) { // DBG( printf( "rotation read error" ) ); } else { rotation.x = x; rotation.y = y; rotation.z = z; } /* Step 2: Read all coordinate points * ---------------------------- */ std::vector<double> points; NODE_LIST coordinates; GetChildsByName( aFaceNode, wxT( "Coordinate" ), coordinates ); PROPERTY_MAP coordinate_properties; // IndexedFaceSet has one Coordinate child node GetNodeProperties( coordinates[0], coordinate_properties ); // Save points to vector as doubles wxStringTokenizer point_tokens( coordinate_properties[ wxT( "point" ) ] ); double point = 0.0; while( point_tokens.HasMoreTokens() ) { if( point_tokens.GetNextToken().ToDouble( &point ) ) { points.push_back( point ); } else { wxLogTrace( traceX3DParser, wxT( "Error converting to double" ) ); } } if( points.size() % 3 != 0 ) { // DBG( printf( "Number of points is incorrect" ) ); return; } /* Create 3D vertex from 3 points and * apply transforms in order of SCALE, ROTATION, TRANSLATION */ wxString vrml_pointlist; std::vector<S3D_VERTEX> triplets; for( unsigned id = 0; id < points.size() / 3; id++ ) { int triplet_indx = id * 3; S3D_VERTEX point( points[ triplet_indx ], points[ triplet_indx + 1 ], points[ triplet_indx + 2 ] ); point.x *= scale.x; point.y *= scale.y; point.z *= scale.z; rotate( point, rotation, angle ); point.x += translation.x; point.y += translation.y; point.z += translation.z; m_model->m_Point.push_back( point ); // VRML vrml_pointlist.Append( wxString::Format( wxT( "%f %f %f\n" ), point.x, point.y, point.z ) ); } vrml_points.push_back( vrml_pointlist ); /* Step 3: Read all color points * ---------------------------- */ std::vector<double> color_points; NODE_LIST color; GetChildsByName( aFaceNode, wxT( "Color" ), color ); // Some models lack color information, need to handle this safely if( !color.empty() ) { PROPERTY_MAP color_properties; // IndexedFaceSet has one Coordinate child node GetNodeProperties( color[0], color_properties ); // Save points to vector as doubles wxStringTokenizer colorpoint_tokens( color_properties[ wxT( "color" ) ] ); double color_point = 0.0; while( colorpoint_tokens.HasMoreTokens() ) { if( colorpoint_tokens.GetNextToken().ToDouble( &color_point ) ) { color_points.push_back( color_point ); } else { wxLogTrace( traceX3DParser, wxT( "Error converting to double" ) ); } } if( color_points.size() % 3 != 0 ) { // DBG( printf( "Number of points is incorrect" ) ); return; } /* Create 3D face color from 3 color points */ m_model->m_Materials->m_DiffuseColor.clear(); for( unsigned id = 0; id < color_points.size() / 3; id++ ) { m_model->m_MaterialIndexPerFace.push_back( id ); int color_triplet_indx = id * 3; glm::vec3 colorface( color_points[ color_triplet_indx + 0 ], color_points[ color_triplet_indx + 1 ], color_points[ color_triplet_indx + 2 ] ); m_model->m_Materials->m_DiffuseColor.push_back( colorface ); } } /* -- Read coordinate indexes -- */ PROPERTY_MAP faceset_properties; GetNodeProperties( aFaceNode, faceset_properties ); wxString coordIndex_str = faceset_properties[ wxT( "coordIndex" ) ]; wxStringTokenizer index_tokens( coordIndex_str ); wxString vrml_coord_indx_list; std::vector<int> coord_list; coord_list.clear(); while( index_tokens.HasMoreTokens() ) { long index = 0; index_tokens.GetNextToken().ToLong( &index ); // -1 marks the end of polygon if( index < 0 ) { /* Step 4: Apply geometry to Master object * --------------------------------------- */ m_model->m_CoordIndex.push_back( coord_list ); coord_list.clear(); vrml_coord_indx_list.Append( wxT( "-1\n" ) ); } else { coord_list.push_back( index ); vrml_coord_indx_list.Append( wxString::Format( wxT( "%ld " ), index ) ); } } vrml_coord_indexes.push_back( vrml_coord_indx_list ); }
PatriciaTrie<S,T>* PatriciaTrie<S,T>::Copy (PatriciaTrieNode<S,T>* root) { PatriciaTrieNode<S,T>* newNode = new PatriciaTrieNode<S,T> (); bool recursiveHead = (root == NULL); if (root == NULL) root = head; newNode->bit_index = root->bit_index; newNode->data = root->data; newNode->key = root->key; // // create the subtrees and wire my children to it // or (if there are no subtrees) wire the children to myself // later we will wire the children correctly with some backedges // if (root->left != NULL && root->left->bit_index > root->bit_index) { PatriciaTrie<S,T>* leftTrie = Copy (root->left); newNode->left = leftTrie->head; leftTrie->head = NULL; delete leftTrie; } else { newNode->left = newNode; } if (root->right != NULL && root->right->bit_index > root->bit_index) { PatriciaTrie<S,T>* rightTrie = Copy (root->right); newNode->right = rightTrie->head; rightTrie->head = NULL; delete rightTrie; } else { newNode->right = newNode; } PatriciaTrie<S,T>* newTrie = new PatriciaTrie<S,T> (); newTrie->head = newNode; // // need to adapt the back edges // if (recursiveHead) { NODE_LIST origNodes = GetNodeList (); NODE_LIST newNodes = newTrie->GetNodeList (); assert (origNodes.size() == newNodes.size()); NODE_LIST_ITERATOR iorigBegin = origNodes.begin (); NODE_LIST_ITERATOR iorigEnd = origNodes.end (); NODE_LIST_ITERATOR inewBegin = newNodes.begin (); NODE_LIST_ITERATOR inewEnd = newNodes.end (); for ( ; iorigBegin != iorigEnd && inewBegin != inewEnd; iorigBegin++, inewBegin++) { PatriciaTrieNode<S,T>* origNode = *iorigBegin; PatriciaTrieNode<S,T>* newNode = *inewBegin; // // make some checks that everything went fine // assert (origNode != newNode && origNode->key == newNode->key && origNode->bit_index == newNode->bit_index && origNode->data == newNode->data ); // // if the original node has backedges: // find the correct backedge node in the new trie // and wire the children correctly // if (origNode->left->bit_index < origNode->bit_index) newNode->left = newTrie->find_bitindex_node (newTrie->head, origNode->left->bit_index); if (origNode->right->bit_index < origNode->bit_index) newNode->right = newTrie->find_bitindex_node (newTrie->head, origNode->right->bit_index); } // for ( ; iorigBegin != iorigEnd && inewBegin != inewEnd; iorigBegin++, inewBegin++) } // if (recursiveHead) return newTrie; }