Exemple #1
0
int LoadMapFiles(INode* node, SContext* sc, MtlBaseLib& mtls, TimeValue t)
{
	NameTab mapFiles;
	CheckFileNames checkNames(&mapFiles);

	node->EnumAuxFiles(checkNames, FILE_ENUM_MISSING_ONLY | FILE_ENUM_1STSUB_MISSING);

	// Check the lights
	for (int i = 0; i < sc->lightTab.Count(); i++) {
		if (((LightInfo*)sc->lightTab[i])->light != NULL) {
			((LightInfo*)sc->lightTab[i])->light->EnumAuxFiles(checkNames, 
				FILE_ENUM_MISSING_ONLY | FILE_ENUM_1STSUB_MISSING);
		}
	}

	if (mapFiles.Count()) {
		// Error! Missing maps.
		// not sure how to handle this so we gladly continue.
			
		//if (MessageBox(hWnd, "There are missing maps.\nDo you want to render anyway?", "Warning!", MB_YESNO) != IDYES) {
		//	return 0;
		//}
	}

	// Load the maps
	MapLoadEnum mapload(t);
	for (i=0; i<mtls.Count(); i++) {
		EnumMaps(mtls[i],-1, mapload);
	}

	return 1;
}
Exemple #2
0
int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL suppressPrompts) {

	IfcGeom::IteratorSettings settings;
	settings.use_world_coords() = false;
	settings.weld_vertices() = true;
	settings.sew_shells() = true;

#ifdef _UNICODE
	int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, name, -1, 0, 0, 0, 0);
	char* fn_mb = new char[fn_buffer_size];
	WideCharToMultiByte(CP_UTF8, 0, name, -1, fn_mb, fn_buffer_size, 0, 0);
#else
	const char* fn_mb = name;
#endif

	IfcGeom::Iterator<float> iterator(settings, fn_mb);

	if (!iterator.initialize()) return false;

	itfc->ProgressStart(_T("Importing file..."), TRUE, fn, NULL);

	MtlBaseLib* mats = itfc->GetSceneMtls();
	int slot = mats->Count();

	std::map<std::vector<std::string>, Mtl*> material_cache;

	do{
		const IfcGeom::TriangulationElement<float>* o = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator.get());

		TSTR o_type = S(o->type());
		TSTR o_guid = S(o->guid());

		Mtl *m = ComposeMultiMaterial(material_cache, mats, itfc, slot, o->geometry().materials(), o->type(), o->geometry().material_ids());

		TriObject* tri = CreateNewTriObject();

		const int numVerts = o->geometry().verts().size()/3;
		tri->mesh.setNumVerts(numVerts);
		for( int i = 0; i < numVerts; i ++ ) {
			tri->mesh.setVert(i,o->geometry().verts()[3*i+0],o->geometry().verts()[3*i+1],o->geometry().verts()[3*i+2]);
		}
		const int numFaces = o->geometry().faces().size()/3;
		tri->mesh.setNumFaces(numFaces);

		bool needs_default = std::find(o->geometry().material_ids().begin(), o->geometry().material_ids().end(), -1) != o->geometry().material_ids().end();

		typedef std::pair<int, int> edge_t;

		std::set<edge_t> face_boundaries;
		for(std::vector<int>::const_iterator it = o->geometry().edges().begin(); it != o->geometry().edges().end();) {
			const int v1 = *it++;
			const int v2 = *it++;

			const edge_t e((std::min)(v1, v2), (std::max)(v1, v2));
			face_boundaries.insert(e);
		}

		for( int i = 0; i < numFaces; i ++ ) {
			const int v1 = o->geometry().faces()[3*i+0];
			const int v2 = o->geometry().faces()[3*i+1];
			const int v3 = o->geometry().faces()[3*i+2];
			
			const edge_t e1((std::min)(v1, v2), (std::max)(v1, v2));
			const edge_t e2((std::min)(v2, v3), (std::max)(v2, v3));
			const edge_t e3((std::min)(v3, v1), (std::max)(v3, v1));

			const bool b1 = face_boundaries.find(e1) != face_boundaries.end();
			const bool b2 = face_boundaries.find(e2) != face_boundaries.end();
			const bool b3 = face_boundaries.find(e3) != face_boundaries.end();

			tri->mesh.faces[i].setVerts(v1, v2, v3);
			tri->mesh.faces[i].setEdgeVisFlags(b1, b2, b3);

			MtlID mtlid = o->geometry().material_ids()[i];
			if (needs_default) {
				mtlid ++;
			}
			tri->mesh.faces[i].setMatID(mtlid);
		}
				
		tri->mesh.buildNormals();
		// Either use this or undefine the FACESETS_AS_COMPOUND option in IfcGeom.h to have
		// properly oriented normals. Using only the line below will result in a consistent
		// orientation of normals accross shells, but not always oriented towards the
		// outside.
		// tri->mesh.UnifyNormals(false);
		tri->mesh.BuildStripsAndEdges();
		tri->mesh.InvalidateTopologyCache();
		tri->mesh.InvalidateGeomCache();

		ImpNode* node = impitfc->CreateNode();
		node->Reference(tri);
		node->SetName(o_guid);
		node->GetINode()->Hide(o->type() == "IfcOpeningElement" || o->type() == "IfcSpace");
		if (m) {
			node->GetINode()->SetMtl(m);
		}
		const std::vector<float>& matrix_data = o->transformation().matrix().data();
		node->SetTransform(0,Matrix3 ( Point3(matrix_data[0],matrix_data[1],matrix_data[2]),Point3(matrix_data[3],matrix_data[4],matrix_data[5]),
			Point3(matrix_data[6],matrix_data[7],matrix_data[8]),Point3(matrix_data[9],matrix_data[10],matrix_data[11]) ));
		impitfc->AddNodeToScene(node);

		itfc->ProgressUpdate(iterator.progress(), true, _T(""));

	} while (iterator.next());

	itfc->ProgressEnd();
	
	return true;
}
static IOResult ImportLibrary(ILoad* iload, MtlBaseLib& lib)
{
	// Get the VIZ Importer/Exporter
	CComPtr<IVIZPointerClient> pPointerClient;
	HRESULT hr = CMaxMaterialCollection::GetXMLImpExp(&pPointerClient);
	if(hr != S_OK)
		return IO_ERROR;

	// Get the export interface
	CComQIPtr<IXmlMaterial> pIMtl = pPointerClient;
	ATLASSERT(pIMtl);
	if(!pIMtl)
		return IO_ERROR;

	// Create an XML document
	CComPtr<IXMLDOMDocument> doc;
	hr = doc.CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER);
	if (hr != S_OK || doc == NULL)
		return IO_ERROR;

	char* xmlStr = NULL;
	IOResult res = iload->ReadCStringChunk(&xmlStr);
	if (res != IO_OK)
		return res;
	if (xmlStr == NULL)
		return IO_OK;
	_bstr_t xml(xmlStr);

	VARIANT_BOOL result;
	hr = doc->loadXML(xml.GetBSTR(), &result);
	if (hr != S_OK || result == 0)
		return IO_ERROR;

	CComBSTR query = "./Materials/Material";
	CComPtr<IXMLDOMNodeList> list;
	hr = doc->selectNodes(query, &list);
	if (hr != S_OK || list == NULL)
		return IO_ERROR;

	long i, len = 0;
	hr = list->get_length(&len);
	if (hr != S_OK)
		return IO_ERROR;

	long failed = 0;
	for (i = 0; i < len ; ++i) {
		CComPtr<IXMLDOMNode> node;
		hr = list->get_item(i, &node);
		if (hr == S_OK && node != NULL) {
			VARIANT vResult;
			vResult.vt = VT_BYREF;
			vResult.byref = NULL;
			hr = pIMtl->ImportMaterial(node, &vResult);
			if(SUCCEEDED(hr) && vResult.vt == VT_BYREF && vResult.byref != NULL)
			{
				lib.Add(static_cast<Mtl*>(vResult.byref));
			}
			else
				++failed;
		}
	}
	
	return failed == 0 ? IO_OK : IO_ERROR;
}
Exemple #4
0
//***************************************************************************
// Calculate ambient or diffuse color at each vertex.
// Pass in TRUE as the "diffuse" parameter to calculate the diffuse color.
// If FALSE is passed in, ambient color is calculated.
//***************************************************************************
BOOL calcMixedVertexColors(INode* node, TimeValue t, int lightModel, ColorTab& vxColTab, EvalColProgressCallback* fn)
{
	ObjectState ostate;
	BOOL deleteTri;
	Mesh* mesh;
	SContext sc;
	DefaultLight dl1, dl2;
	MtlBaseLib mtls;
	Matrix3 tm;

	sc.SetNodeAndTime(node, t);
	tm = sc.tmAfterWSM;

	TriObject* tri = GetTriObjectFromNode(node, t, deleteTri);

	// We will only work on GeomObjects
	if (!tri) {
		return FALSE;
	}

	// Get the mesh from the object
	mesh = &tri->GetMesh();
	if (!mesh) {
		return FALSE;
	}

	// If the node doesn't have a material attached,
	// we create a dummy material.
	Mtl* mtl = node->GetMtl();
	if (!mtl) {
		mtl = new DumMtl(Color(node->GetWireColor()));
	}

	mesh->buildRenderNormals();

	vxColTab.ZeroCount();
	vxColTab.Shrink();

	sc.SetMesh(mesh);
	sc.CalcBoundObj();

	// Add the material to the list
	mtls.AddMtl(mtl);

	// Setup ambient light
	if (lightModel == LIGHT_AMBIENT) {
		sc.SetAmbientLight(Color(1.0f, 1.0f, 1.0f));
	}
	else {
		sc.SetAmbientLight(Color(0.0f, 0.0f, 0.0f));
	}

	// If we're using the real lights, we need to find them first
	if (lightModel == LIGHT_SCENELIGHT) {
		AddSceneLights(&sc, &mtls);

		// Add default lights if there are no lights in the scene
		if (sc.lightTab.Count() == 0) {
			dl1.ls.intens = 1.0f;
			dl1.ls.color = Color(0.8f, 0.8f, 0.8f);
			dl1.ls.type = OMNI_LGT;
			dl1.tm = TransMatrix(1000.0f * Point3(-900.0f, -1000.0f, 1500.0f));

			dl2.ls.intens = 1.0f;
			dl2.ls.color = Color(0.8f, 0.8f, 0.8f);
			dl2.ls.type = OMNI_LGT;
			dl2.tm = TransMatrix(-1000.0f * Point3(-900.0f, -1000.0f, 1500.0f));

			sc.AddLight(new LightInfo(&dl1));
			sc.AddLight(new LightInfo(&dl2));
		}

		sc.SetAmbientLight(GetCOREInterface()->GetAmbient(t, FOREVER));
	}

	sc.UpdateLights();
	// Update material
	mtl->Update(t, FOREVER);
	
	int numVerts = mesh->numVerts;
	for (unsigned int v = 0; v < (unsigned)numVerts; v++) {

		if (fn) {
			if (fn->progress(float(v)/float(numVerts))) {
				if (deleteTri) {
					delete tri;
				}

				mtls.Empty();

				if (mtl->ClassID() == DUMMTL_CLASS_ID) {
					delete mtl;
				}

				// What to return here is up for discussion.
				// 1) We are aborting so FALSE might be in order.
				// 2) We have calculated some colors. Let's use what we've got so far.
				return TRUE;
			}
		}

		// Create a new entry
		Color* vxCol = new Color;
		Point3 tmpCol(0.0f, 0.0f, 0.0f);

		int numShades = 0;
		BitArray faceList;
		faceList.SetSize(mesh->numFaces, 0);

		// Get vertex normal
		// We also pass in a BitArray that will be filled in with
		// to inform us to which faces this vertex belongs.
		// We could do this manually, but we need to do it to get
		// the vertex normal anyway so this is done to speed things
		// up a bit.
		Point3 vxNormal = interpVertexNormal(mesh, tm, v, faceList);
		Point3 viewDir = -vxNormal;
		Point3 viewPoint = tm*mesh->verts[v] + 5.0f*vxNormal;
		Point3 lightPos = viewPoint;
		Point3 viewTarget = tm*mesh->verts[v];

		// We now have a viewpoint and a view target.
		// Now we just have to shade this point on the mesh in order
		// to get it's color.
		// Note: 
		// Since materials are assigned on Face basis we need to render each
		// vertex as many times as it has connecting faces.
		// the colors collected are mixed to get the resulting
		// color at each vertex.
		
		for (int nf = 0; nf < faceList.GetSize(); nf++) {
			if (faceList[nf]) {
				// render vertex for this face.
				sc.SetViewPoint(viewPoint);
				sc.SetTargetPoint(viewTarget);
				sc.SetViewDir(viewDir);
				sc.SetFaceNum(nf);
				Face* f = &mesh->faces[nf];
				sc.SetMtlNum(f->getMatID());
				sc.CalcNormals();

				// Setup the barycentric coordinate
				if (mesh->faces[nf].v[0] == v)
					sc.SetBaryCoord(Point3(1.0f, 0.0f, 0.0f));
				else if (mesh->faces[nf].v[1] == v)
					sc.SetBaryCoord(Point3(0.0f, 1.0f, 0.0f));
				else if (mesh->faces[nf].v[2] == v)
					sc.SetBaryCoord(Point3(0.0f, 0.0f, 1.0f));

				// Use diffuse color instead of ambient
				// The only difference is that we create a special light
				// located at the viewpoint and we set the ambient light to black.
				if (lightModel == LIGHT_DIFFUSE) {
					dl1.ls.intens = 1.0f;
					dl1.ls.color = Color(0.8f, 0.8f, 0.8f);
					dl1.ls.type = OMNI_LGT;
					dl1.tm = TransMatrix(lightPos);

					sc.ClearLights();
					sc.AddLight(new LightInfo(&dl1));
					sc.UpdateLights();
				}


				// Shade the vertex
				mtl->Shade(sc);

				tmpCol.x += sc.out.c.r;
				tmpCol.y += sc.out.c.g;
				tmpCol.z += sc.out.c.b;
				numShades++;
			}
		}

		// The color mixes. We just add the colors together and 
		// then divide with as many colors as we added.
		if (numShades > 0) {
			tmpCol = tmpCol / (float)numShades;
		}

		
		vxCol->r = tmpCol.x;
		vxCol->g = tmpCol.y;
		vxCol->b = tmpCol.z;

		
		vxCol->ClampMinMax();

		
		// Append the Color to the table. If the array needs
		// to be realloc'ed, allocate extra space for 100 points.
		vxColTab.Append(1, &vxCol, 100);
	}

	// Some objects gives us a temporary mesh that we need to delete afterwards.
	if (deleteTri) {
		delete tri;
	}


	mtls.Empty();

	if (mtl->ClassID() == DUMMTL_CLASS_ID) {
		delete mtl;
	}

	return TRUE;
}
Exemple #5
0
int GetMaps::proc(ReferenceMaker *rm)
{
	if (IsTex((MtlBase*)rm))
		mlib->AddMtl((MtlBase *)rm);
	return REF_ENUM_CONTINUE;
}
Exemple #6
0
void GetMaps::proc(ReferenceMaker *rm)
{
	if (IsTex((MtlBase*)rm)) {
		mlib->AddMtl((MtlBase *)rm);
	}
}