CLODMeshGenerator::CLODMeshGenerator() : GeometryGeneratorBase() { vertexCount = 0; faceCount = 0; patchID = 0; meshNumber = 0; // Needed for progress calculation meshAttributes = mlU3D::MESH_ATTRIBUTES_DEFAULT; _wem = NULL; ML_CHECK_NEW(_wem, WEM()); }
//! Write one block to file stream. (private) bool U3DFileWriter::_writeBlockToFileStream(U3DDataBlockWriter& block, std::ofstream& ofstream) { bool Success = false; MLuint32 flushBufferSize = block.getNumTotalBytes(); mlU3D::DataBlockFundamental* flushBuffer = NULL; ML_CHECK_NEW(flushBuffer, mlU3D::DataBlockFundamental[flushBufferSize]); memset(flushBuffer, 0, flushBufferSize); if (NULL != flushBuffer) { // Add Block type, Data size & Meta data Size mlU3D::DataBlockFundamental flushBufferIndex = 0; flushBuffer[flushBufferIndex] = block.blockType; flushBufferIndex++; flushBuffer[flushBufferIndex] = block.getDataSizeWithChildDataBytes(); flushBufferIndex++; flushBuffer[flushBufferIndex] = block.getMetaDataSizeWithoutPadding(); flushBufferIndex++; // Add Data mlU3D::DataVector data = block.getData(); for (mlU3D::DataBlockFundamental i = 0; i < block.getDataSize(); i++) { flushBuffer[flushBufferIndex] = data[i]; flushBufferIndex++; } // Add Meta data mlU3D::DataVector metaData = block.getMetaData(); for (mlU3D::DataBlockFundamental i = 0; i < block.getMetaDataSize(); i++) { flushBuffer[flushBufferIndex] = metaData[i]; flushBufferIndex++; } } else { flushBufferSize = 0; } if ((0 != flushBufferSize) && (block.blockType != 0)) { try { ofstream.write(reinterpret_cast<char*>(flushBuffer), flushBufferSize); ofstream.flush(); Success = true; } catch (...) { // Ignore errors } } ML_DELETE_ARRAY(flushBuffer); return Success; }
void TileSphere::addPoint(float* position) { ML_TRACE_IN("void TileSphere::addPoint(float* position) "); // Adds a point into the tile sphere. float minX=0, maxX=0, minY=0, maxY=0, minZ=0, maxZ=0; int counter = 0; // If the sphere has sub spheres, add point into the according sub sphere. if (_hasSubSpheresFlag) { for (counter = 0; counter < _cubicPartition; counter++) { _tileSpheres[counter]._getBB(minX, maxX, minY, maxY, minZ, maxZ); if ((*(position) >= minX) && (*(position) <= maxX) && (*(position + 1) >= minY) && (*(position + 1) <= maxY) && (*(position + 2) >= minZ) && (*(position + 2) <= maxZ)) { _tileSpheres[counter].addPoint(position); } } } else { // If there is no further sub-division, integrate point into subset. _subset[_numEntries] = position; _numEntries++; // If capacity is reached, establish sub spheres and transfer the containing points. if (_numEntries == static_cast<unsigned int>(_maxEntries)) { // Establish further sub spheres. if (_hasSubSpheresFlag == false) { ML_DELETE_ARR(_tileSpheres); ML_CHECK_NEW (_tileSpheres, TileSphere[_cubicPartition]); _hasSubSpheresFlag = true; } int xCounter=0, yCounter=0, zCounter=0; float partitionDiv = 1.0f / static_cast<float>(_partition); float stepX = (_maxX - _minX) * partitionDiv; float stepY = (_maxY - _minY) * partitionDiv; float stepZ = (_maxZ - _minZ) * partitionDiv; float newMaxX = 0.0f; float newMaxY = 0.0f; float newMaxZ = 0.0f; // Constitute BBs for the sub spheres. for (xCounter = 0; xCounter < _partition; xCounter++) { for (yCounter = 0; yCounter < _partition; yCounter++) { for (zCounter = 0; zCounter < _partition; zCounter++) { _tileSpheres[counter].setParameter(_minimalDistance, _partition, _numEntries, _error); // to avoid rounding errors, take the real maximum value at the upper border newMaxX = (xCounter+1 < _partition) ? (_minX + stepX * xCounter + stepX) : _maxX; newMaxY = (yCounter+1 < _partition) ? (_minY + stepY * yCounter + stepY) : _maxY; newMaxZ = (zCounter+1 < _partition) ? (_minZ + stepZ * zCounter + stepZ) : _maxZ; _tileSpheres[counter].setBB( _minX + stepX * xCounter, newMaxX, _minY + stepY * yCounter, newMaxY, _minZ + stepZ * zCounter, newMaxZ); counter++; } } } // Transfer points for (counter = 0; counter < _maxEntries; counter++){ addPoint(_subset[counter]); } } } }
void SavePRC::savePRCToFileStream(std::ofstream& ofstream) { _progressFld->setFloatValue(0.0f); WEMPtr saveWEM = NULL; ML_CHECK_NEW(saveWEM,WEM()); // Clear object info vector; _prcObjectInfoVector.clear(); // Clear geometry vectors _pointSetsGeometryVector.clear(); _lineSetsGeometryVector.clear(); PRCMeshInfoVector meshInfoVector; // Stores the model bounding box data & its center. Shall be modified only with UpdateBoundingBox() method! ModelBoundingBoxStruct modelBoundingBox; modelBoundingBox.start.x = ML_DOUBLE_MAX; modelBoundingBox.start.y = ML_DOUBLE_MAX; modelBoundingBox.start.z = ML_DOUBLE_MAX; modelBoundingBox.end.x = ML_DOUBLE_MAX * -1; modelBoundingBox.end.y = ML_DOUBLE_MAX * -1; modelBoundingBox.end.z = ML_DOUBLE_MAX * -1; // Get default parameters from field values //defaultValues = getDefaultValuesFromFields(); // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ _statusFld->setStringValue("Analyzing input data."); // Scan all data from input field and collect base info for point sets. PreProcessPointSetData(modelBoundingBox); // Scan all data from input field and collect base info for line sets. PreProcessLineSetData(modelBoundingBox); // Scan all WEM patches, triangulate them if necessary and collect base info. PreProcessMeshData(saveWEM, meshInfoVector, modelBoundingBox); GroupNodeVector groupNodes = assemblePRCGroupNodeInfo(_prcObjectInfoVector); mapParentTreeNodeIDs(_prcObjectInfoVector, groupNodes); _modelTree = assemblePRCModelTreeInfo(groupNodes); // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ _progressFld->setFloatValue(0.1f); PRCFile outPRCFile(ofstream); PRCModelTreeNode modelRootNode = getNodeFromPRCModelTree(_modelTree, 0); WriteNodeModelsToPRCFile(outPRCFile, modelRootNode); outPRCFile.finish(); _progressFld->setFloatValue(1.0f); }
void CSODistance::_process() { ML_TRACE_IN("void CSODistance::_process()"); _outputXMarkerList->clearList(); // Delete all created CurveData objects while ( !_outputCurveList->getCurveList().empty() ) { ML_DELETE( _outputCurveList->getCurveList().back() ); _outputCurveList->getCurveList().pop_back(); } if (_csoList0 != NULL) { int nCSOs = _csoList0->numCSO(); double minDistance = 0.0; double maxDistance = 0.0; double avgDistance = 0.0; double stdDevDistance = 0.0; std::stringstream distances; distances << _tableHeader << std::endl; switch ( _modeFld->getEnumValue() ){ case FIRST2 : { if ((nCSOs >= 2) && (_csoList0->getCSOAt(0)->getIsFinished()) && (_csoList0->getCSOAt(1)->getIsFinished())) { std::vector<vec3>pointSet1; std::vector<vec3>pointSet2; _csoList0->getCSOAt(0)->fillPathPointCoordinatesFlattened(pointSet1); _csoList0->getCSOAt(1)->fillPathPointCoordinatesFlattened(pointSet2); Vector3 minPoint1,minPoint2,maxPoint1,maxPoint2; MinimalDistancePointClouds* pointSetsMinDist = NULL; ML_CHECK_NEW(pointSetsMinDist, MinimalDistancePointClouds); pointSetsMinDist->setPointSets(pointSet1, pointSet2); pointSetsMinDist->setNumEntries(200); pointSetsMinDist->computeDistance(minPoint1,minPoint2); minDistance = sqrt((minPoint1[0]-minPoint2[0])*(minPoint1[0]-minPoint2[0]) + (minPoint1[1]-minPoint2[1])*(minPoint1[1]-minPoint2[1]) + (minPoint1[2]-minPoint2[2])*(minPoint1[2]-minPoint2[2])); _minimumDistanceFld->setFloatValue( static_cast<float>(minDistance)); _outputXMarkerList->appendItem(XMarker( vec6(minPoint1[0],minPoint1[1],minPoint1[2],0.5f,0.0f,0.0f), vec3(minPoint2[0]-minPoint1[0],minPoint2[1]-minPoint1[1],minPoint2[2]-minPoint1[2]), 0,"")); distances << _csoList0->getCSOAt(0)->getId() << "," << _csoList0->getCSOAt(1)->getId() << "," << minDistance << "," << maxDistance << "," << avgDistance << "," << stdDevDistance << std::endl; } else { _minimumDistancePoint1Fld->setVec3fValue(vec3(0.0,0.0,0.0)); _minimumDistancePoint2Fld->setVec3fValue(vec3(0.0,0.0,0.0)); _minimumDistanceFld->setFloatValue(0.0f); _distancesFld->setStringValue( _tableHeader ); } break; } case INPLANE: case INDEX: { CurveData *outputCurve = new CurveData; double *yValues = new double[ nCSOs ]; double minDist = ML_DOUBLE_MAX; vec3 point1; vec3 point2; double averageMinDistance = 0.0; double averageMeanDistance = 0.0; double averageMaxDistance = 0.0; for ( int iCSO = 0; iCSO<nCSOs; ++iCSO ){ CSO* currentCSO = _csoList0->getCSOAt( iCSO ); CSO* matchingCSO = _findMatchingCSO(iCSO); if (!matchingCSO) {continue;} std::vector<vec3>pointSet1; std::vector<vec3>pointSet2; currentCSO->fillPathPointCoordinatesFlattened(pointSet1); matchingCSO->fillPathPointCoordinatesFlattened(pointSet2); Vector3 minPoint1,minPoint2,maxPoint1,maxPoint2; _getDistances( pointSet1, pointSet2, minDistance,maxDistance,avgDistance,stdDevDistance, minPoint1,minPoint2,maxPoint1,maxPoint2); averageMinDistance += minDistance; averageMeanDistance += avgDistance; averageMaxDistance += maxDistance; distances << currentCSO->getId() << "," << matchingCSO->getId() << "," << minDistance << "," << maxDistance << "," << avgDistance << "," << stdDevDistance << std::endl; if ( minDistance < minDist ){ minDist = minDistance; point1 = minPoint1; point2 = minPoint2; } _outputXMarkerList->appendItem(XMarker( vec6(minPoint1[0],minPoint1[1],minPoint1[2],0.5f,0.0f,0.0f), vec3(minPoint2[0]-minPoint1[0],minPoint2[1]-minPoint1[1],minPoint2[2]-minPoint1[2]), currentCSO->getId(),"")); switch ( _curveStatistic->getEnumValue() ){ case MIN: yValues[ iCSO ] = minDistance; break; case MAX: yValues[ iCSO ] = maxDistance; break; case MEAN: yValues[ iCSO ] = avgDistance; break; case STDEV: yValues[ iCSO ] = stdDevDistance; break; default: break; } } // iCSO averageMinDistance /= (nCSOs != 0 ? nCSOs : 1.0); averageMeanDistance /= (nCSOs != 0 ? nCSOs : 1.0); averageMaxDistance /= (nCSOs != 0 ? nCSOs : 1.0); outputCurve->setY( nCSOs, yValues); delete[] yValues; _outputCurveList->getCurveList().push_back( outputCurve ); _distancesFld->setStringValue( distances.str() ); _minimumDistancePoint1Fld->setVec3fValue(point1); _minimumDistancePoint2Fld->setVec3fValue(point2); _minimumDistanceFld->setFloatValue( static_cast<float>(minDistance) ); _AverageMinimumDistanceFld->setDoubleValue( averageMinDistance ); _AverageMeanDistanceFld->setDoubleValue( averageMeanDistance ); _AverageMaxDistanceFld->setDoubleValue( averageMaxDistance ); break; } default: break; } } else { _minimumDistancePoint1Fld->setVec3fValue(vec3(0.0,0.0,0.0)); _minimumDistancePoint2Fld->setVec3fValue(vec3(0.0,0.0,0.0)); _minimumDistanceFld->setFloatValue(0.0f); _distancesFld->setStringValue( _tableHeader ); } _outputXMarkerListFld->setBaseValue(_outputXMarkerList); _outputCurveListFld->touch(); }
CSODistance::CSODistance() : BaseOp(0, 0) { ML_TRACE_IN("CSODistance::CSODistance(int numInImages, int numOutImages) : BaseOp(numInImages, numOutImages)"); handleNotificationOff(); _csoList0 = NULL; _csoList1 = NULL; _tableHeader = "Id1,Id2,min,max,mean,stdDev"; FieldContainer* fieldC = getFieldContainer(); ML_CHECK(fieldC); (_input0CSOFld = fieldC->addBase("inCSOList"))->setBaseValue(NULL); (_input1CSOFld = fieldC->addBase("inCSOList1"))->setBaseValue(NULL); ////////////////////////////////////////////////////////////////////////// char* distanceModes[LASTMODE]; distanceModes[ FIRST2 ] = "First 2 CSOs"; distanceModes[ INPLANE ] = "Match in plane"; distanceModes[ INDEX ] = "Match index"; _modeFld = fieldC->addEnum("mode",distanceModes,LASTMODE); _modeFld->setEnumValue( FIRST2 ); ////////////////////////////////////////////////////////////////////////// (_minimumDistanceFld = fieldC->addFloat("minimumDistance"))->setFloatValue(0); (_minimumDistancePoint1Fld = fieldC->addVec3f("minimumDistancePoint1"))->setVec3fValue(vec3(0.0,0.0,0.0)); (_minimumDistancePoint2Fld = fieldC->addVec3f("minimumDistancePoint2"))->setVec3fValue(vec3(0.0,0.0,0.0)); _distancesFld = addString("distances",_tableHeader ); _AverageMinimumDistanceFld = addDouble("averageMinimumDistance", 0.0 ); _AverageMeanDistanceFld = addDouble("averageMeanDistance", 0.0 ); _AverageMaxDistanceFld = addDouble("averageMaximumDistance", 0.0 ); ////////////////////////////////////////////////////////////////////////// _tolleranceFld = addDouble("tollerance", 0.0001 ); ////////////////////////////////////////////////////////////////////////// _applyFld = fieldC->addNotify("apply"); (_autoApplyFld = fieldC->addBool("autoApply"))->setBoolValue(true); _statusFld = fieldC->addString("status"); _statusFld->setStringValue("Ready"); ////////////////////////////////////////////////////////////////////////// (_listenToRepaintNotificationsFld = fieldC->addBool("listenToRepaintNotifications")) ->setBoolValue(false); (_listenToFinishingNotificationsFld = fieldC->addBool("listenToFinishingNotifications")) ->setBoolValue(true); (_listenToSelectionChangedNotificationsFld = fieldC->addBool("listenToSelectionChangedNotifications")) ->setBoolValue(false); char* statisticsNames[LASTSTATISTIC]; statisticsNames[ MIN ] = "Minimum"; statisticsNames[ MAX ] = "Maximum"; statisticsNames[ MEAN ] = "Mean"; statisticsNames[ STDEV ] = "StDev"; _curveStatistic = addEnum("curveStatistic",statisticsNames,LASTSTATISTIC ); _isInNotificationCB = false; ML_CHECK_NEW(_outputXMarkerList,XMarkerList()); (_outputXMarkerListFld = getFieldContainer()->addBase("outputXMarkerList"))->setBaseValue(NULL); _outputCurveList = new CurveList; (_outputCurveListFld = getFieldContainer()->addBase("outputCurveList"))->setBaseValue( _outputCurveList ); handleNotificationOn(); }
void DicomSurfaceSegmentationLoad::_addMeshToOutput(const int meshNumber) { if(meshNumber >= _dicomMeshesVector.size()) { return; } int meshesIDStartValue = (int)_meshesIDStartValueFld->getIntValue(); const Element3D meshElement = _dicomMeshesVector[meshNumber]; const std::string segmentLabel = meshElement.getSegmentLabel(); const Coordinates3D meshSurface = meshElement.getReferencedSurface(); const std::vector<Vector3> wemPositions = meshSurface.getCoordinates(); const std::vector<unsigned long> meshPositionIndices = meshSurface.getCoordinateIndices(); const std::vector<Vector3> meshNormals = meshSurface.getNormals(); WEMTrianglePatch* newPatch = NULL; ML_CHECK_NEW(newPatch, WEMTrianglePatch()); // Add WEM nodes for (unsigned long p = 0; p < wemPositions.size(); p++) { WEMNode* newNode = newPatch->addNode(); newNode->setPosition(wemPositions[p]); if(!meshNormals.empty()) { newNode->setNormal(meshNormals[p]); } else { newNode->computeNormal(); } } // Add WEM faces for (size_t f = 0; f < meshPositionIndices.size(); f += 3) { WEMTriangle* newFace = newPatch->addTriangle(); for (unsigned int i = 0; i < 3; i++) { WEMNode* node = newPatch->getNodeAt(meshPositionIndices[f+i]); newFace->setNode(i, node); node->addFace(newFace); } newFace->computeNormal(); } newPatch->setLabel(segmentLabel); //newPatch->setId(_outWEM->getCurrentWEMPatchId()); newPatch->setId(meshesIDStartValue + meshNumber); newPatch->setType(_type); ML_NAMESPACE::WEMPrimitiveValueList* primitiveValueList = newPatch->createOrGetPrimitiveValueList("LUT"); primitiveValueList->setValue(0, static_cast<double>(meshNumber)); newPatch->buildEdgeConnectivity(); _outWEM->addWEMPatch(newPatch); _finish(newPatch); }
void GraphToFibers::_updateOutput() { _outNodePositions.clearList(); _outNodePositions.selectItemAt(-1); _outEdgePositions.clearList(); _outEdgePositions.selectItemAt(-1); _outEdgeConnections.clearList(); _outEdgeConnections.selectItemAt(-1); int nodeCount = 0; int edgeCount = 0; int currentEdgePositionNum = 0; // Work on a local copy of the graph, because the smoothing will change it Graph* vesselGraph = NULL; ML_CHECK_NEW(vesselGraph, Graph(_inGraph)); vesselGraph->purifyGraph(); //vesselGraph->setRootIdToAllChildren(); vesselGraph->closeSkeletonGaps(); // smooth the graph const int numSmoothingPasses = 3; const float smoothingFactor = 0.7; //const Graph::EdgeIterator endEdge(); for (Graph::EdgeIterator iter = vesselGraph->beginEdge(); iter != vesselGraph->endEdge(); ++iter) { static_cast<VesselEdge*>(*iter)->smooth(numSmoothingPasses, smoothingFactor, smoothingFactor); } // Iterate over all root nodes for (Graph::ConstNodeIterator iter = vesselGraph->beginRoot(); iter != vesselGraph->endRoot(); iter++) { } // Iterate over all nodes for (Graph::ConstNodeIterator i = vesselGraph->beginNode(); i != vesselGraph->endNode(); i++) { const VesselNode* thisNode = *i; const Vector3 thisNodePos = thisNode->getPos(); //thisNode->getDepNode(); // Get dependent node via edge with index i. //thisNode->edges(); //thisNode->getId(); //thisNode->getLabel(); // Add node markers XMarker thisNodeMarker(thisNodePos); std::string nodeName = "Node #" + mlPDF::intToString(nodeCount); thisNodeMarker.setName(nodeName.c_str()); thisNodeMarker.type = 0; _outNodePositions.appendItem(thisNodeMarker); // Add edge markers & connections const size_t thisNodeEdgesNum = thisNode->getEdgeNum(); // Get Number of edges dependent to the node. for (size_t e = 0; e < thisNodeEdgesNum; e++) { const VesselEdge* thisNodeEdge = thisNode->getDepEdge(e); // Get the pointer of edge with index i. if (thisNodeEdge) { bool newBranch = true; const size_t numSkeletons = thisNodeEdge->numSkeletons(); for (size_t s = 0; s < numSkeletons; s++) { const Skeleton* thisSkeleton = thisNodeEdge->skeleton(s); Vector3 thisSkeletonPos = thisSkeleton->getPos(); XMarker thisVesselEdgeMarker(thisSkeletonPos); thisVesselEdgeMarker.type = 0; // edgeCount; std::string edgeName = "Centerlines"; //std::string edgeName = "Edge #" + mlPDF::intToString(edgeCount); thisVesselEdgeMarker.setName(edgeName.c_str()); _outEdgePositions.appendItem(thisVesselEdgeMarker); /* if (s < numSkeletons - 1) { IndexPair thisVesselEdgeConnection((int)s, (int)s + 1); thisVesselEdgeConnection.type = edgeCount; _outEdgeConnections.appendItem(thisVesselEdgeConnection); } */ if (!newBranch) { IndexPair thisVesselEdgeConnection(currentEdgePositionNum - 1, currentEdgePositionNum); thisVesselEdgeConnection.type = 0; _outEdgeConnections.appendItem(thisVesselEdgeConnection); } currentEdgePositionNum++; newBranch = false; } edgeCount++; } } nodeCount++; } ML_DELETE(vesselGraph); _outNodePositionsFld->touch(); _outEdgePositionsFld->touch(); _outEdgeConnectionsFld->touch(); _createFibers(); }
ML_START_NAMESPACE //*********************************************************************************** void SavePRC::PreProcessMeshData(WEMPtr saveWEM, PRCMeshInfoVector &meshInfoVector, ModelBoundingBoxStruct& boundingBox) { if (!_inWEM) { return; } MLuint32 meshNumber = 0; bool simpleMode = _simpleModeMeshFld->getBoolValue(); StringVector meshSpecificationsVector; if (simpleMode) { //meshSpecificationsVector.push_back("<U3DMesh>"); } else { meshSpecificationsVector = getObjectSpecificationsStringFromUI(_meshSpecificationFld, "<Mesh>"); } // Scan all WEM patches, triangulate them if necessary and collect base info. WEMPatch* wemPatch = NULL; WEMTrianglePatch* addedTrianglePatch = NULL; _statusFld->setStringValue("Analyzing mesh specification and input WEM."); const MLuint32 numberOfWEMPatches = _inWEM->getNumWEMPatches(); for (MLuint32 i = 0; i < numberOfWEMPatches; i++) { PRCMeshInfoStruct thisWEMMeshInfo; wemPatch = _inWEM->getWEMPatchAt(i); addedTrianglePatch = NULL; const unsigned int newId = saveWEM->getCurrentWEMPatchId(); if (wemPatch->getNumFaces() > 0) { if (wemPatch->getPatchType() != WEM_PATCH_TRIANGLES) { WEMTrianglePatch* triangulatedPatch = NULL; ML_CHECK_NEW(triangulatedPatch,WEMTrianglePatch()); wemPatch->triangulate(triangulatedPatch, WEM_TRIANGULATION_STRIP); addedTrianglePatch = saveWEM->addWEMPatchCopy(triangulatedPatch); addedTrianglePatch->computeBoundingBox(); ML_DELETE(triangulatedPatch); } else { addedTrianglePatch = saveWEM->addWEMPatchCopy(reinterpret_cast<WEMTrianglePatch*>(wemPatch)); } if (addedTrianglePatch != NULL) { addedTrianglePatch->setId(newId); // Adjust properties of main WEM bounding box WEMBoundingBox* thisWEMPatchBoundingBox = addedTrianglePatch->getBoundingBox(); ModelBoundingBoxStruct newboundingBox; newboundingBox.start = thisWEMPatchBoundingBox->getMin(); newboundingBox.end = thisWEMPatchBoundingBox->getMax(); UpdateBoundingBox(boundingBox, newboundingBox); std::string wemDescription = addedTrianglePatch->getDescription(); std::string wemLabel = addedTrianglePatch->getLabel(); SpecificationParametersStruct thisSpecificationParameters; // Create an artificial meshSpecificationVector if only WEM label & description shall be used if (simpleMode) { meshSpecificationsVector.clear(); // Parse WEM label & description... std::string u3dModelName = getSpecificParameterFromWEMDescription(wemDescription, "ModelName"); std::string u3dGroupName = getSpecificParameterFromWEMDescription(wemDescription, "GroupName"); std::string u3dGroupPath = ""; if ("" != u3dModelName) { u3dGroupPath = "/" + u3dModelName + "/"; } if ("" != u3dGroupName) { if ("" == u3dGroupPath) { u3dGroupPath += "/"; } u3dGroupPath += u3dGroupName + "/"; } std::string displayName = wemLabel; if (displayName == "") { displayName = "Mesh " + intToString(i+1); } // ...and write data into meshSpecification string std::string meshSpecificationsString = "<U3DMesh>"; meshSpecificationsString += "<WEMLabel>" + wemLabel + "</WEMLabel>"; meshSpecificationsString += "<ObjectName>" + displayName + "</ObjectName>"; meshSpecificationsString += "<GroupPath>" + u3dGroupPath + "</GroupPath>"; meshSpecificationsString += "<Color>" + getSpecificParameterFromWEMDescription(wemDescription, "Color") + "</Color>"; meshSpecificationsString += "<SpecularColor>" + getSpecificParameterFromWEMDescription(wemDescription, "SpecularColor") + "</SpecularColor>"; meshSpecificationsString += "<ModelVisibility>3</ModelVisibility>"; // Add meshSpecification string to meshSpecificationVector meshSpecificationsVector.push_back(meshSpecificationsString); } for (int thisSpecificationIndex = 0; thisSpecificationIndex < meshSpecificationsVector.size(); thisSpecificationIndex++) { thisSpecificationParameters = getAllSpecificationParametersFromString(meshSpecificationsVector[thisSpecificationIndex]); if (thisSpecificationParameters.WEMLabel == wemLabel) { PRCObjectInfoStruct thisPRCObjectInfo = CreateNewPRCObjectInfo(i,PRCOBJECTTYPE_MESH, thisSpecificationParameters.ObjectName, defaultValues); thisPRCObjectInfo.GroupPath = thisSpecificationParameters.GroupPath; thisPRCObjectInfo.ParentTreeNodeID = -1; thisPRCObjectInfo.RGBAColor = getColorVec4(thisSpecificationParameters.Color, Vector4(0)); // If alpha = 0 -> Adobe doesn't render; _prcObjectInfoVector.push_back(thisPRCObjectInfo); // Collect mesh info thisWEMMeshInfo.DiffuseColorCount = 0; // This is not really needed in this version thisWEMMeshInfo.SpecularColorCount = 0; // This is not really needed in this version thisWEMMeshInfo.TextureCoordCount = 0; // This is not really needed in this version thisWEMMeshInfo.DefaultAmbientColor = defaultValues.defaultMaterialAmbientColor; thisWEMMeshInfo.DefaultSpecularColor = defaultValues.defaultMaterialSpecularColor; thisWEMMeshInfo.DefaultDiffuseColor = defaultValues.defaultMaterialDiffuseColorWithTransparency; thisWEMMeshInfo.DefaultEmissiveColor = defaultValues.defaultMaterialEmissiveColor; thisWEMMeshInfo.FaceCount = addedTrianglePatch->getNumFaces(); thisWEMMeshInfo.NormalCount = addedTrianglePatch->getNumFaces(); thisWEMMeshInfo.VertexCount = addedTrianglePatch->getNumNodes(); thisWEMMeshInfo.PatchID = addedTrianglePatch->getId(); // thisWEMMeshInfo.MeshAttributes = U3D_MESH_ATTRIBUTES_DEFAULT; // thisWEMMeshInfo.MeshAttributes |= ( (thisWEMMeshInfo.NormalCount == 0) ? U3D_MESH_ATTRIBUTES_EXCLUDENORMALS : 0 ); // thisWEMMeshInfo.ShadingAttributes = U3D_SHADINGATTRIBUTES_NONE; // thisWEMMeshInfo.ShadingAttributes |= ( (thisWEMMeshInfo.DiffuseColorCount > 0) ? U3D_SHADINGATTRIBUTES_DIFFUSECOLORS : 0 ); // Should not happen in this version // thisWEMMeshInfo.ShadingAttributes |= ( (thisWEMMeshInfo.SpecularColorCount > 0) ? U3D_SHADINGATTRIBUTES_SPECULARCOLORS : 0 ); // Should not happen in this version // thisWEMMeshInfo.ResourceName = thisPRCObjectInfo.ResourceName; thisWEMMeshInfo.MeshNumber = meshNumber++; meshInfoVector.push_back(thisWEMMeshInfo); } } } // if (addedTrianglePatch != NULL) } // if (wemPatch->getNumFaces() > 0) wemPatch = NULL; } }