SceneObject *ContourSurfacePluginInterface::CreateObject() { IbisAPI *ibisAPI = GetIbisAPI(); Q_ASSERT(ibisAPI); m_generatedSurface = vtkSmartPointer<GeneratedSurface>::New(); m_generatedSurface->SetPluginInterface( this ); if( ibisAPI->IsLoadingScene() ) { ibisAPI->AddObject(m_generatedSurface); return m_generatedSurface; } // If we have a current object we build surface now SceneObject *obj = ibisAPI->GetCurrentObject(); if (obj->IsA("ImageObject")) { ImageObject *image = ImageObject::SafeDownCast(obj); double imageRange[2]; image->GetImageScalarRange(imageRange); double contourValue = imageRange[0]+(imageRange[1]-imageRange[0])/5.0; //the best seems to be 20% of max, tested on Colin27 m_generatedSurface->SetImageObjectID( image->GetObjectID() ); m_generatedSurface->SetContourValue(contourValue); m_generatedSurface->SetGaussianSmoothingFlag(true); if ( m_generatedSurface->GenerateSurface() ) { QString surfaceName(image->GetName()); int n = surfaceName.lastIndexOf('.'); if (n < 0) surfaceName.append("_surface"); else { surfaceName.replace(n, surfaceName.size()-n, "_surface"); } surfaceName.append(QString::number(image->GetNumberOfChildren())); m_generatedSurface->SetName(surfaceName); m_generatedSurface->SetScalarsVisible(0); ibisAPI->AddObject(m_generatedSurface, image); ibisAPI->SetCurrentObject( m_generatedSurface ); } return m_generatedSurface; } QMessageBox::warning( 0, "Error!", "Current object should be an ImageObject" ); return NULL; }
void PolyDataObject::Export() { Q_ASSERT( this->GetManager() ); QString surfaceName(this->Name); surfaceName.append(".vtk"); this->SetDataFileName(surfaceName); QString fullName(this->GetManager()->GetSceneDirectory()); fullName.append("/"); fullName.append(surfaceName); QString saveName = Application::GetInstance().GetFileNameSave( tr("Save Object"), fullName, tr("*.vtk") ); if(saveName.isEmpty()) return; if (QFile::exists(saveName)) { int ret = QMessageBox::warning(0, tr("Save PolyDataObject"), saveName, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape); if (ret == QMessageBox::No) return; } this->SavePolyData( saveName ); }
MObject readNurbs(double iFrame, Alembic::AbcGeom::INuPatch & iNode, MObject & iObject) { MStatus status; MObject obj; Alembic::AbcGeom::INuPatchSchema schema = iNode.getSchema(); // no interpolation for now Alembic::AbcCoreAbstract::index_t index, ceilIndex; getWeightAndIndex(iFrame, schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex); Alembic::AbcGeom::INuPatchSchema::Sample samp; schema.get(samp, Alembic::Abc::ISampleSelector(index)); Alembic::Abc::P3fArraySamplePtr pos = samp.getPositions(); Alembic::Abc::FloatArraySamplePtr weights = samp.getPositionWeights(); MString surfaceName(iNode.getName().c_str()); unsigned int degreeU = samp.getUOrder() - 1; unsigned int degreeV = samp.getVOrder() - 1; unsigned int numCVInU = samp.getNumU(); unsigned int numCVInV = samp.getNumV(); // cv points unsigned int numCV = numCVInU*numCVInV; unsigned int curPos = 0; MPointArray controlVertices; controlVertices.setLength(numCV); for (unsigned int v = 0; v < numCVInV; ++v) { for (unsigned int u = 0; u < numCVInU; ++u, ++curPos) { unsigned int mayaIndex = u * numCVInV + (numCVInV - v - 1); MPoint pt((*pos)[curPos].x, (*pos)[curPos].y, (*pos)[curPos].z); if (weights) { pt.w = (*weights)[curPos]; } // go from u,v order to reversed v, u order controlVertices.set(pt, mayaIndex); } } // Nurbs form // Alemblic file does not record the form of nurb surface, we get the form // by checking the CV data. If the first degree number CV overlap the last // degree number CV, then the form is kPeriodic. If only the first CV overlaps // the last CV, then the form is kClosed. MFnNurbsSurface::Form formU = MFnNurbsSurface::kPeriodic; MFnNurbsSurface::Form formV = MFnNurbsSurface::kPeriodic; // Check all curves bool notOpen = true; for (unsigned int v = 0; notOpen && v < numCVInV; v++) { for (unsigned int u = 0; u < degreeU; u++) { unsigned int firstIndex = u * numCVInV + (numCVInV - v - 1); unsigned int lastPeriodicIndex = (numCVInU - degreeU + u) * numCVInV + (numCVInV - v - 1); if (!controlVertices[firstIndex].isEquivalent(controlVertices[lastPeriodicIndex])) { formU = MFnNurbsSurface::kOpen; notOpen = false; break; } } } if (formU == MFnNurbsSurface::kOpen) { formU = MFnNurbsSurface::kClosed; for (unsigned int v = 0; v < numCVInV; v++) { unsigned int lastUIndex = (numCVInU - 1) * numCVInV + (numCVInV - v - 1); if (! controlVertices[numCVInV-v-1].isEquivalent(controlVertices[lastUIndex])) { formU = MFnNurbsSurface::kOpen; break; } } } notOpen = true; for (unsigned int u = 0; notOpen && u < numCVInU; u++) { for (unsigned int v = 0; v < degreeV; v++) { unsigned int firstIndex = u * numCVInV + (numCVInV - v - 1); unsigned int lastPeriodicIndex = u * numCVInV + (degreeV - v - 1); //numV - (numV - vDegree + v) - 1; if (!controlVertices[firstIndex].isEquivalent(controlVertices[lastPeriodicIndex])) { formV = MFnNurbsSurface::kOpen; notOpen = false; break; } } } if (formV == MFnNurbsSurface::kOpen) { formV = MFnNurbsSurface::kClosed; for (unsigned int u = 0; u < numCVInU; u++) { if (! controlVertices[u * numCVInV + (numCVInV-1)].isEquivalent(controlVertices[u * numCVInV])) { formV = MFnNurbsSurface::kOpen; break; } } } Alembic::Abc::FloatArraySamplePtr uKnot = samp.getUKnot(); Alembic::Abc::FloatArraySamplePtr vKnot = samp.getVKnot(); unsigned int numKnotsInU = static_cast<unsigned int>(uKnot->size() - 2); MDoubleArray uKnotSequences; uKnotSequences.setLength(numKnotsInU); for (unsigned int i = 0; i < numKnotsInU; ++i) { uKnotSequences.set((*uKnot)[i+1], i); } unsigned int numKnotsInV = static_cast<unsigned int>(vKnot->size() - 2); MDoubleArray vKnotSequences; vKnotSequences.setLength(numKnotsInV); for (unsigned int i = 0; i < numKnotsInV; i++) { vKnotSequences.set((*vKnot)[i+1], i); } // Node creation try the API first MFnNurbsSurface mFn; obj = mFn.create(controlVertices, uKnotSequences, vKnotSequences, degreeU, degreeV, formU, formV, true, iObject, &status); // something went wrong, try open/open create if (status != MS::kSuccess && (formU != MFnNurbsSurface::kOpen || formV != MFnNurbsSurface::kOpen)) { obj = mFn.create(controlVertices, uKnotSequences, vKnotSequences, degreeU, degreeV, MFnNurbsSurface::kOpen, MFnNurbsSurface::kOpen, true, iObject, &status); } if (status == MS::kSuccess) { mFn.setName(surfaceName); } else { MString errorMsg = "Could not create Nurbs Surface: "; errorMsg += surfaceName; MGlobal::displayError(errorMsg); } trimSurface(samp, mFn); return obj; }
// Chunk doesnt inlcude its tag and size size void CLwoWriter::BuildChunkLengths() { MSG_DEBUG("Building LWO chunks length..."); ulong tagsSize = 0; { // Surfaces CLwoFile::CLayer::SurfaceMap& surfaces = m_curLayer.GetSurfaceMap(); CLwoFile::CLayer::SurfaceMap::iterator surfaceIt, surfaceEnd; surfaceEnd = surfaces.end(); for(surfaceIt = surfaces.begin(); surfaceIt != surfaceEnd; ++surfaceIt) // For each part name tagsSize += GetStringSize(surfaceIt->first); // Parts CLwoFile::CLayer::PartVector& parts = m_curLayer.GetPartVector(); CLwoFile::CLayer::PartVector::iterator partIt, partEnd; partEnd = parts.end(); for(partIt = parts.begin(); partIt != partEnd; ++partIt) // For each part name tagsSize += GetStringSize(*partIt); // Smoothing groups CLwoFile::CLayer::SGVector& sgs = m_curLayer.GetSGVector(); tagsSize += sgs.size() * GetStringSize("sgXX"); } ulong vertexPosCount = m_curLayer.GetVertexPositionVector().size(); ulong vmapTexCount = 0; ulong vmadTexCount = 0; { CLwoFile::CLayer::TexCoordMap& texCoords = m_curLayer.GetTexCoordMap(); CLwoFile::CLayer::TexCoordMap::iterator texCoordIt, texCoordEnd; texCoordEnd = texCoords.end(); std::vector< CLwoFile::CLayer::CTexCoord > texCoordVector; for(texCoordIt = texCoords.begin(); texCoordIt != texCoordEnd; ++texCoordIt) // For each LWO texCoord { texCoordVector = texCoordIt->second; std::vector< CLwoFile::CLayer::CTexCoord >::iterator texCoordVectorIt, texCoordVectorEnd; texCoordVectorEnd = texCoordVector.end(); for(texCoordVectorIt = texCoordVector.begin(); texCoordVectorIt != texCoordVectorEnd; ++texCoordVectorIt) // For each LWO face { if(texCoordVectorIt == texCoordVector.begin()) // skip the first one since its in the VMAP { ++vmapTexCount; continue; } ++vmadTexCount; } } } // Indexed vertices count ulong faceCount = 0; ulong vertexPolyCount = 0; { CLwoFile::CLayer::FaceVector& faces = m_curLayer.GetFaceVector(); faceCount = faces.size(); CLwoFile::CLayer::FaceVector::iterator faceIt, faceBegin, faceEnd; faceBegin = faces.begin(); faceEnd = faces.end(); for(faceIt = faceBegin; faceIt != faceEnd; ++faceIt) // for each LWO point vertexPolyCount += faceIt->VertexCount(); } //Images ulong imageCount = 0; ulong imagesSize = 0; { CLwoFile::CLayer::ImageVector& images = m_curLayer.GetImageVector(); imageCount = images.size(); CLwoFile::CLayer::ImageVector::iterator imageIt, imageEnd; imageEnd = images.end(); imageIt = images.begin(); // first image only for(imageIt = images.begin(); imageIt != imageEnd; ++imageIt) // for each LWO image { imagesSize += 4; // index of the image imagesSize += 6; // "STIL" + size of still imagesSize += GetStringSize(*imageIt); // size of path } } // TAGS (every surface names + part names + sg names) m_chunkLengthMap[CLwoFile::CHUNK_TAGS] = tagsSize; // LAYR m_chunkLengthMap[CLwoFile::CHUNK_LAYR] = 18; // blank layer // PNTS m_chunkLengthMap[CLwoFile::CHUNK_PNTS] = vertexPosCount * 12; // number of vertex in this mesh * 12 // VMAP | TXUV m_chunkLengthMap[CLwoFile::CHUNK_VMAP] = 4 + 2 + 8 + vmapTexCount * (2+8); // "TXUV" + dimension(short) + "txuv00\0\0" + vertexPos*(vIndex+UV) // VMAD | TXUV m_chunkLengthMap[CLwoFile::CHUNK_VMAD] = 4 + 2 + 8 + vmadTexCount * (2+2+8); // "TXUV" + dimension(short) + "txuv00\0\0" + texCoordCount*(pointIndex+polyIndex+UV) // POLS m_chunkLengthMap[CLwoFile::CHUNK_POLS] = 4 + vertexPolyCount * 2 + faceCount * 2; // "FACE" + for each face : vertex Number(short) + index per vertex(short) // PTAG m_chunkLengthMap[CLwoFile::CHUNK_PTAG] = 4 + faceCount * 4; // "SURF" or "PART" or "SMGP" + face number * 4 // CLIP m_chunkLengthMap[CLwoFile::CHUNK_CLIP] = imagesSize; // "STIL" sub-chunk // SURF constant sub-chunks { m_chunkLengthMap[CLwoFile::CHUNK_BLOK] = (6+50) + (6+104) + (92); // IMAP + TMAP + rest = 244 m_chunkLengthMap[CLwoFile::CHUNK_COLR] = 14; m_chunkLengthMap[CLwoFile::CHUNK_DIFF] = 6; } // Surfaces ulong surfacesSize = 0; CLwoFile::CLayer::SurfaceMap& surfaces = m_curLayer.GetSurfaceMap(); ulong surfaceCount = surfaces.size(); CLwoFile::CLayer::SurfaceMap::iterator surfaceIt, surfaceEnd; surfaceEnd = surfaces.end(); for(surfaceIt = surfaces.begin(); surfaceIt != surfaceEnd; ++surfaceIt) // For each surface { std::string surfaceName(surfaceIt->first); CLwoFile::CLayer::CSurface& surface = surfaceIt->second; bool bHasTex = (surface.m_imageIndex != -1); m_chunkLengthMap[CLwoFile::CHUNK_SURF] = GetStringSize(surfaceName) + 2 + // surface name + parent name "\0\0" (bHasTex ? (6 + m_chunkLengthMap[CLwoFile::CHUNK_BLOK]):0) + (6 + m_chunkLengthMap[CLwoFile::CHUNK_COLR]) + (6 + m_chunkLengthMap[CLwoFile::CHUNK_DIFF]); surface.m_size = m_chunkLengthMap[CLwoFile::CHUNK_SURF]; surfacesSize += m_chunkLengthMap[CLwoFile::CHUNK_SURF]; } // FORM m_chunkLengthMap[CLwoFile::CHUNK_FORM] = (4) + // LWO2 (8 + m_chunkLengthMap[CLwoFile::CHUNK_TAGS]) + // "TAGS" + size + chunk... (8 + m_chunkLengthMap[CLwoFile::CHUNK_LAYR]) + // "LAYR" (8 + m_chunkLengthMap[CLwoFile::CHUNK_PNTS]) + // "PNTS" (vmapTexCount > 0 ? (8 + m_chunkLengthMap[CLwoFile::CHUNK_VMAP]):0) + // "VMAP" (vmapTexCount > 0 ? (8 + m_chunkLengthMap[CLwoFile::CHUNK_VMAD]):0) + // "VMAD" // If VMAP, sure to have VMAD! (8 + m_chunkLengthMap[CLwoFile::CHUNK_POLS]) + // "POLS" (8 + m_chunkLengthMap[CLwoFile::CHUNK_PTAG]) + // ("PTAG" + size) + "SURF" + data (8 + m_chunkLengthMap[CLwoFile::CHUNK_PTAG]) + // "PART" (8 + m_chunkLengthMap[CLwoFile::CHUNK_PTAG]) + // "SMGP" imageCount*8 + m_chunkLengthMap[CLwoFile::CHUNK_CLIP] + // "CLIP" surfaceCount*8 + surfacesSize; // "SURF" }
// Surface bool CLwoWriter::WriteSurfaces() { // surface tag names CLwoFile::CLayer::SurfaceMap& surfaces = m_curLayer.GetSurfaceMap(); CLwoFile::CLayer::SurfaceMap::iterator surfaceIt, surfaceEnd; surfaceEnd = surfaces.end(); for(surfaceIt = surfaces.begin(); surfaceIt != surfaceEnd; ++surfaceIt) // For each surface { std::string surfaceName(surfaceIt->first); CLwoFile::CLayer::CSurface& surface = surfaceIt->second; MSG_DEBUG("SURF: '" << surfaceName << "'"); // "SURF" + size WriteTag(CLwoFile::CHUNK_SURF); WriteLong(surface.m_size); // hack for surface, in fact, it should be like this for everything // surface name OBJ_ASSERT(surfaceName == surface.GetSurfaceName()); WriteString(surfaceName); // parent/source name std::string parentLayerName(""); WriteString(parentLayerName); // SURF | COLR { MSG_DEBUG("SURF | COLR"); WriteTag(CLwoFile::CHUNK_COLR); ushort colr_size = (ushort)(m_chunkLengthMap[CLwoFile::CHUNK_COLR]); WriteShort(colr_size); // Color Vector3D color(3); color[0] = 0.78431f; color[1] = 0.78431f; color[2] = 0.78431f; WriteVector3D(color); // Envl ushort envl = 0; WriteShort(envl); } // SURF | DIFF { MSG_DEBUG("SURF | DIFF"); WriteTag(CLwoFile::CHUNK_DIFF); ushort diff_size = (ushort)(m_chunkLengthMap[CLwoFile::CHUNK_DIFF]); WriteShort(diff_size); float diffuse = 1.0f; WriteFloat(diffuse); ushort lumi = 0; WriteShort(lumi); } // SURF | BLOK if(surface.m_imageIndex != -1) // there is an image index { MSG_DEBUG("SURF | BLOK"); // BLOK WriteTag(CLwoFile::CHUNK_BLOK); WriteShort((ushort)m_chunkLengthMap[CLwoFile::CHUNK_BLOK]); // SURF | BLOK | IMAP { MSG_DEBUG("SURF | BLOK | IMAP"); // IMAP WriteTag(CLwoFile::CHUNK_IMAP); m_chunkLengthMap[CLwoFile::CHUNK_IMAP] = 50; WriteShort((ushort)m_chunkLengthMap[CLwoFile::CHUNK_IMAP]); // IMAP size { ushort ordStrCmp = 0x8000; WriteShort(ordStrCmp); // Ordinal string compare function // CHAN WriteTag(CLwoFile::CHUNK_CHAN); WriteShort(4); // CHAN size WriteTag(CLwoFile::CHUNK_COLR); // OPAC WriteTag(CLwoFile::CHUNK_OPAC); WriteShort(8); // OPAC size WriteShort(0); WriteFloat(1.0f); WriteShort(0); // ENAB WriteTag(CLwoFile::CHUNK_ENAB); WriteShort(2); // ENAB size WriteShort(1); // NEGA WriteTag(CLwoFile::CHUNK_NEGA); WriteShort(2); // NEGA size WriteShort(0); // AXIS WriteTag(CLwoFile::CHUNK_AXIS); WriteShort(2); // AXIS size WriteShort(1); } } // SURF | BLOK | TMAP { MSG_DEBUG("SURF | BLOK | TMAP"); // TMAP WriteTag(CLwoFile::CHUNK_TMAP); ushort imap_size = 104; WriteShort(imap_size); { // CNTR WriteTag(CLwoFile::CHUNK_CNTR); WriteShort(14); // CHAN size Vector3D center(3); WriteVector3D(center); WriteShort(0); // SIZE WriteTag(CLwoFile::CHUNK_SIZE); WriteShort(14); // SIZE size Vector3D size(3); size[0] = 1.0f; size[1] = 1.0f; size[2] = 1.0f; WriteVector3D(size); WriteShort(0); // ROTA WriteTag(CLwoFile::CHUNK_ROTA); WriteShort(14); // ROTA size Vector3D rota(3); WriteVector3D(rota); WriteShort(0); // FALL WriteTag(CLwoFile::CHUNK_FALL); WriteShort(16); // FALL size WriteShort(0); Vector3D fall(3); WriteVector3D(fall); WriteShort(0); // OREF WriteTag(CLwoFile::CHUNK_OREF); WriteShort(8); // OREF size WriteString(std::string("(none)")); // CSYS WriteTag(CLwoFile::CHUNK_CSYS); WriteShort(2); // CSYS size WriteShort(0); } } // PROJ : projection WriteTag(CLwoFile::CHUNK_PROJ); WriteShort(2); // PROJ size WriteShort(5); // UV projection mapping // AXIS WriteTag(CLwoFile::CHUNK_AXIS); WriteShort(2); // AXIS size WriteShort(2); // IMAG WriteTag(CLwoFile::CHUNK_IMAG); WriteShort(2); // IMAG size WriteShort(surface.m_imageIndex); // Write the image index corresponding to imageVector // WRAP WriteTag(CLwoFile::CHUNK_WRAP); WriteShort(4); // WRAP size WriteShort(1); WriteShort(1); // WRPW WriteTag(CLwoFile::CHUNK_WRPW); WriteShort(6); // WRPW size WriteFloat(1.0f); WriteShort(0); // WRPH WriteTag(CLwoFile::CHUNK_WRPH); WriteShort(6); // WRPH size WriteFloat(1.0f); WriteShort(0); // VMAP WriteTag(CLwoFile::CHUNK_VMAP); WriteShort(8); // VMAP size WriteString("txuv00"); // TODO : increment for multiple meshes? // AAST WriteTag(CLwoFile::CHUNK_AAST); WriteShort(6); // AAST size WriteShort(1); WriteFloat(1.0f); // PIXB WriteTag(CLwoFile::CHUNK_PIXB); WriteShort(2); // PIXB size WriteShort(1); } } return true; }