// -------------------------------------------------------------------------- void CFabAtHomeDoc::OnChunkImportgeometry() // -------------------------------------------------------------------------- { // import an stl file or vector data file CFabAtHomeApp *pApp = (CFabAtHomeApp*)AfxGetApp(); if (!pApp->printer.EnsureCurrentTool(true)) { pApp->Log("Please ensure that a valid tool configuration file is loaded and mounted before connect the hardware."); return; } CString startDir; startDir.Format("%s\\*.stl",pApp->modelsDir); CFileDialog dlg(TRUE, "stl", (LPCTSTR)startDir, OFN_ALLOWMULTISELECT, "Geometry File (*.stl)|*.stl|Vector File (*.vct, *.txt)|*.vct;*.txt|All Files (*.*)|*.*||", 0); if (dlg.DoModal() == IDOK) { //get the dialog path POSITION pos( dlg.GetStartPosition() ); while( pos ) { CString dlgPathName( dlg.GetNextPathName(pos) ); pApp->modelsDir.Format("%s",dlgPathName); BeginWaitCursor(); CChunk newchunk; //peel the name out of the path int idx; CString chunkName = pApp->modelsDir; while((idx=chunkName.Find('\\')) != -1) { chunkName = chunkName.Right(chunkName.GetLength()-idx-1); } //make sure it is not a duplicate name CSingleLock modelLock(&model.m_mutAccess); modelLock.Lock(); for(int i = 0; i < model.chunk.GetSize(); i++) { int nameCnt = 1; //if a duplicate is found, append a number while(chunkName.Compare(model.chunk[i].GetName())==0) { CString tmp = chunkName; chunkName.Format("%s-%d",tmp,nameCnt); nameCnt++; } } //check the type of file being imported bool ok = false; if((chunkName.Find(".vct") >= 0) || (chunkName.Find(".VCT") >=0) || (chunkName.Find(".txt") >= 0) || (chunkName.Find(".TXT") >=0)) { //import a vector file ok = newchunk.geometry.LoadVCT(pApp->modelsDir); newchunk.SetType(CHUNKTYPE_VCT); } else if ((chunkName.Find(".stl") >= 0) || (chunkName.Find(".STL") >= 0)) { //import an stl file ok = newchunk.geometry.LoadSTL(pApp->modelsDir); newchunk.SetType(CHUNKTYPE_STL); } else { ((CFabAtHomeApp *)AfxGetApp())->Log("Cannot import files of this type"); return; } EndWaitCursor(); if (!ok) { ((CFabAtHomeApp *)AfxGetApp())->Log("Cannot open file for reading "+pApp->modelsDir); return; } //now set the name of the chunk newchunk.SetName(chunkName); newchunk.materialname = "Undefined"; newchunk.toolname = "Undefined"; newchunk.color = CVec(0.5,0.5,0.5); newchunk.alpha = 1; newchunk.id = model.GetNewId(); model.chunk.Add(newchunk); } model.FocusCentroid(); model.Flush(); model.InvalidateBuild(); model.InvalidateProcess(); SetModifiedFlag(); UpdateAllViews(0); pApp->printer.SetModelPtr(&model); model.SelectAll(); CVec pmax,pmin; model.ComputeBoundingBox(pmax,pmin); if(pmin.z < 0) { CString msg; msg.Format("Warning - model extends below table surface!\nPlease move to origin or translate %0.3fmm in z direction.", -(min(pmin.z,pmax.z))); AfxMessageBox(msg,MB_OK); } } }
void MeshUtil::splitModel( Model* model, Mesh* mesh ) { // split by main axis OBBox box = model->boundBox(); Vector3 axis = box.rotation().getColumn(0); Vector3 point = box.translation(); float plane[4] = { axis.x, axis.y, axis.z, -(point.dot(axis)) }; // count number of polygons on each side (in/out sides) VertexAndIndexLock<Model> modelLock( model, Model::LOCK_READ ); int vertsOut = 0; int vertsIn = 0; int indicesOut = 0; int indicesIn = 0; Vector<bool> vertsUsedOut( Allocator<bool>(__FILE__) ); Vector<bool> vertsUsedIn( Allocator<bool>(__FILE__) ); Vector<bool> faceIn( Allocator<bool>(__FILE__) ); vertsUsedOut.setSize( model->vertices(), false ); vertsUsedIn.setSize( model->vertices(), false ); faceIn.setSize( model->indices()/3, false ); faceIn.clear(); for ( int i = 0 ; i < model->indices() ; i += 3 ) { // get face vertices and classify them (in/out) int face[3]; model->getIndices( i, face, 3 ); Vector3 verts[3]; int outcode = 0; for ( int k = 0 ; k < 3 ; ++k ) { model->getVertexPositions( face[k], verts+k, 1 ); if ( verts[k].x*plane[0] + verts[k].y*plane[1] + verts[k].z*plane[2] + plane[3] > 0.f ) outcode |= (1<<k); } if ( 0 == outcode || (7 != outcode && 0 != (i&1)) ) // odd intersecting faces { // in / intersects odd faceIn.add( true ); indicesIn += 3; for ( int k = 0 ; k < 3 ; ++k ) { if ( !vertsUsedIn[face[k]] ) { vertsUsedIn[face[k]] = true; ++vertsIn; } } } else // if ( 7 == outcode ) { // out / intersects even faceIn.add( false ); indicesOut += 3; for ( int k = 0 ; k < 3 ; ++k ) { if ( !vertsUsedOut[face[k]] ) { vertsUsedOut[face[k]] = true; ++vertsOut; } } } } if ( indicesIn < 3 || indicesOut < 3 ) { // nothing to split mesh->addPrimitive( model ); return; } Debug::println( "sgu: Splitting mesh {0} model ({1,#} polys) to two ({2,#} and {3,#} polys)", mesh->name(), model->indices()/3, indicesIn/3, indicesOut/3 ); // build primitives Vector<int> vertexRemap( Allocator<int>(__FILE__) ); int modelFaceIndex; // In P(Model) modelIn = new Model( vertsIn, indicesIn, model->vertexFormat(), model->usage() ); VertexAndIndexLock<Model> modelInLock( modelIn, Model::LOCK_READWRITE ); vertexRemap.clear(); vertexRemap.setSize( model->vertices(), -1 ); int vertIn = 0; for ( int i = 0 ; i < model->vertices() ; ++i ) { if ( vertsUsedIn[i] ) { modelIn->copyVertices( vertIn, model, i, 1 ); vertexRemap[i] = vertIn; ++vertIn; } } assert( vertIn == vertsIn ); modelFaceIndex = 0; int indexIn = 0; for ( int i = 0 ; i < model->indices() ; i += 3 ) { if ( faceIn[modelFaceIndex] ) { int face[3]; model->getIndices( i, face, 3 ); for ( int k = 0 ; k < 3 ; ++k ) face[k] = vertexRemap[ face[k] ]; modelIn->setIndices( indexIn, face, 3 ); indexIn += 3; } ++modelFaceIndex; } assert( indexIn == indicesIn ); modelIn->setShader( model->shader() ); mesh->addPrimitive( modelIn ); // Out P(Model) modelOut = new Model( vertsOut, indicesOut, model->vertexFormat(), model->usage() ); VertexAndIndexLock<Model> modelOutLock( modelOut, Model::LOCK_READWRITE ); vertexRemap.clear(); vertexRemap.setSize( model->vertices(), -1 ); int vertOut = 0; for ( int i = 0 ; i < model->vertices() ; ++i ) { if ( vertsUsedOut[i] ) { modelOut->copyVertices( vertOut, model, i, 1 ); vertexRemap[i] = vertOut; ++vertOut; } } assert( vertOut == vertsOut ); modelFaceIndex = 0; int indexOut = 0; for ( int i = 0 ; i < model->indices() ; i += 3 ) { if ( !faceIn[modelFaceIndex] ) { int face[3]; model->getIndices( i, face, 3 ); for ( int k = 0 ; k < 3 ; ++k ) face[k] = vertexRemap[ face[k] ]; modelOut->setIndices( indexOut, face, 3 ); indexOut += 3; } ++modelFaceIndex; } assert( indexOut == indicesOut ); modelOut->setShader( model->shader() ); mesh->addPrimitive( modelOut ); assert( model->indices() == modelIn->indices()+modelOut->indices() ); }