Ejemplo n.º 1
0
// --------------------------------------------------------------------------
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);
        }
    }

}
Ejemplo n.º 2
0
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() );
}