示例#1
0
文件: file_io.cpp 项目: UG4/ugcore
bool SaveGridHierarchyTransformed(MultiGrid& mg, ISubsetHandler& sh,
								  const char* filename, number offset)
{
	PROFILE_FUNC_GROUP("grid");
	APosition aPos;
//	uses auto-attach
	Grid::AttachmentAccessor<Vertex, APosition> aaPos(mg, aPos, true);

//	copy the existing position to aPos. We take care of dimension differences.
//	Note:	if the method was implemented for domains, this could be implemented
//			in a nicer way.
	if(mg.has_vertex_attachment(aPosition))
		ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition, aPos);
	else if(mg.has_vertex_attachment(aPosition2))
		ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition2, aPos);
	else if(mg.has_vertex_attachment(aPosition1))
		ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition1, aPos);

//	iterate through all vertices and apply an offset depending on their level.
	for(size_t lvl = 0; lvl < mg.num_levels(); ++lvl){
		for(VertexIterator iter = mg.begin<Vertex>(lvl);
			iter != mg.end<Vertex>(lvl); ++iter)
		{
			aaPos[*iter].z() += (number)lvl * offset;
		}
	}

//	finally save the grid
	bool writeSuccess = SaveGridToFile(mg, sh, filename, aPos);

//	clean up
	mg.detach_from_vertices(aPos);

	return writeSuccess;
}
示例#2
0
文件: file_io.cpp 项目: UG4/ugcore
void CopyGridLevel(MultiGrid& srcMG, Grid& destGrid,
				   ISubsetHandler& srcSH, ISubsetHandler& destSH,
				   int lvl, TAPos aPos)
{
	Grid::VertexAttachmentAccessor<TAPos> aaPos(destGrid, aPos);
	Grid::VertexAttachmentAccessor<TAPos> aaSrcPos(srcMG, aPos);
	GridObjectCollection goc = srcMG.get_grid_objects();

	AVertex aNewVrt;
	srcMG.attach_to_vertices(aNewVrt);
	Grid::VertexAttachmentAccessor<AVertex> aaNewVrt(srcMG, aNewVrt);

	for(int si = destSH.num_subsets(); si < srcSH.num_subsets(); ++si)
	{
		destSH.subset_info(si) = srcSH.subset_info(si);
	}

	for(VertexIterator vrtIter = goc.begin<Vertex>(lvl); vrtIter != goc.end<Vertex>(lvl); ++vrtIter)
	{
		Vertex* srcVrt  = *vrtIter;
		Vertex* destVrt = *destGrid.create_by_cloning(srcVrt);

		aaNewVrt[srcVrt] = destVrt;
		aaPos[destVrt] = aaSrcPos[srcVrt];
		destSH.assign_subset(destVrt, srcSH.get_subset_index(srcVrt));
	}

	CopyGridLevelElements<Edge>(srcMG, destGrid, srcSH, destSH, lvl, aNewVrt);
	CopyGridLevelElements<Face>(srcMG, destGrid, srcSH, destSH, lvl, aNewVrt);
	CopyGridLevelElements<Volume>(srcMG, destGrid, srcSH, destSH, lvl, aNewVrt);

	srcMG.detach_from_vertices(aNewVrt);
}
示例#3
0
void RemoveDoubles(Grid& grid, const TVrtIterator& iterBegin,
					const TVrtIterator& iterEnd, Attachment<MathVector<dim> >& aPos,
					number threshold)
{
	if(!grid.has_vertex_attachment(aPos))
		return;

	typedef Attachment<MathVector<dim> > attachment_type;
	Grid::VertexAttachmentAccessor<attachment_type> aaPos(grid, aPos);

	RemoveDoubles<dim>(grid, iterBegin, iterEnd, aaPos, threshold);
}
示例#4
0
bool CalculateVertexNormals(Grid& grid, APosition& aPos, ANormal& aNorm)
{
    if(!grid.has_attachment<Vertex>(aPos))
        return false;
    if(!grid.has_attachment<Vertex>(aNorm))
        grid.attach_to<Vertex>(aNorm);

    Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
    Grid::VertexAttachmentAccessor<ANormal> aaNorm(grid, aNorm);

    return CalculateVertexNormals(grid, aaPos, aaNorm);
}
示例#5
0
文件: file_io.cpp 项目: UG4/ugcore
bool SaveSurfaceViewTransformed(MultiGrid& mg, const SurfaceView& sv,
								const char* filename, number offset)
{
	PROFILE_FUNC_GROUP("grid");

	APosition aPos;
//	uses auto-attach
	Grid::AttachmentAccessor<Vertex, APosition> aaPos(mg, aPos, true);

//	copy the existing position to aPos. We take care of dimension differences.
//	Note:	if the method was implemented for domains, this could be implemented
//			in a nicer way.
	if(mg.has_vertex_attachment(aPosition))
		ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition, aPos);
	else if(mg.has_vertex_attachment(aPosition2))
		ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition2, aPos);
	else if(mg.has_vertex_attachment(aPosition1))
		ConvertMathVectorAttachmentValues<Vertex>(mg, aPosition1, aPos);

//	iterate through all vertices and apply an offset depending on their level.
	for(size_t lvl = 0; lvl < mg.num_levels(); ++lvl){
		for(VertexIterator iter = mg.begin<Vertex>(lvl);
			iter != mg.end<Vertex>(lvl); ++iter)
		{
			aaPos[*iter].z() += (number)lvl * offset;
		}
	}

//	create a subset handler which holds different subsets for the different interface types
	SubsetHandler sh(mg);

	AssignSubsetsBySurfaceViewState<Vertex>(sh, sv, mg);
	AssignSubsetsBySurfaceViewState<Edge>(sh, sv, mg);
	AssignSubsetsBySurfaceViewState<Face>(sh, sv, mg);
	AssignSubsetsBySurfaceViewState<Volume>(sh, sv, mg);

	AssignSubsetColors(sh);
	EraseEmptySubsets(sh);

//	finally save the grid
	bool writeSuccess = SaveGridToFile(mg, sh, filename, aPos);

//	clean up
	mg.detach_from_vertices(aPos);

	return writeSuccess;
}
示例#6
0
///	Creates an Icosahedron
void GenerateIcosahedron(Grid& grid, const vector3& center,
						 number radius, AVector3& aPos)
{
	const number A = 0.85065080835204;
	const number B = 0.525731112119134;

//	create the vertices
	const number coords[12][3] = {	{-B, A, 0}, {0, B, A}, {B, A, 0}, {0, B, -A},
									{-A, 0, B}, {A, 0, B}, {A, 0, -B}, {-A, 0, -B},
									{-B, -A, 0}, {0, -B, A}, {B, -A, 0}, {0, -B, -A}};

	const int inds[20][3] = {	{0, 1, 2}, {0, 2, 3},
								{3, 7, 0}, {7, 4, 0}, {0, 4, 1},
								{1, 5, 2}, {5, 6, 2}, {2, 6, 3},
								{4, 9, 1}, {1, 9, 5}, {7, 3, 11}, {3, 6, 11},
								{11, 8, 7}, {7, 8, 4}, {8, 9, 4},
								{9, 10, 5}, {10, 6, 5}, {10, 11, 6},
								{8, 10, 9}, {8, 11, 10}};

	Vertex* vrts[12];

	if(!grid.has_vertex_attachment(aPos))
		grid.attach_to_vertices(aPos);
	Grid::AttachmentAccessor<Vertex, AVector3> aaPos(grid, aPos);

	for(size_t i = 0; i < 12; ++i){
		vrts[i] = *grid.create<RegularVertex>();
		aaPos[vrts[i]] = vector3(coords[i][0], coords[i][1], coords[i][2]);
		VecScaleAdd(aaPos[vrts[i]], 1.0, center, radius, aaPos[vrts[i]]);
	}

//	construct triangles
	for(size_t i = 0; i < 20; ++i){
		grid.create<Triangle>(TriangleDescriptor(vrts[inds[i][0]], vrts[inds[i][1]],
												 vrts[inds[i][2]]));
	}
}
示例#7
0
bool SaveGridToNCDF(Grid& grid, const char* filename,
					ISubsetHandler* pSH,
					APosition aPos)
{
//	open the file to which we'll write
	ofstream out(filename);
	if(!out)
		return false;

//	access subset-handler
	if(!pSH){
		UG_LOG("ERROR: SubsetHandler required for NCDF (Exodus) export.\n");
		return false;
	}

	ISubsetHandler& sh = *pSH;

//	access the position attachment
	if(!grid.has_vertex_attachment(aPos))
		return false;

	if(grid.num_volumes() != grid.num<Tetrahedron>()){
		UG_LOG("Saving grid to EXODUS-format.\n"
				<< "  WARNING: only Tetrahedrons exported in the moment.\n");
	}

	Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);

//	assign vertex indices
	AInt aInt;
	grid.attach_to_vertices(aInt);
	Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aInt);
	AssignIndices(grid.vertices_begin(), grid.vertices_end(), aaInt, 1);

//	write exodus header
	int var4 = 4;
	out << "netcdf object {" << endl;
	out << "dimensions:" << endl;
	out << "\tlen_string = 33 ;" << endl;
	out << "\tlen_line = 81 ;" << endl;
	out << "\tfour = " << var4 << " ;" << endl;
	out << "\ttime_step = UNLIMITED ;" << endl;
	out << "\tnum_dim = 3 ;" << endl;
	out << "\tnum_nodes = " << grid.num_vertices() << " ;" << endl;
	out << "\tnum_elem = " << grid.num<Tetrahedron>() << " ;" << endl;
	out << "\tnum_el_blk = " << sh.num_subsets() << " ;" << endl;

	for(int i = 0; i < sh.num_subsets(); ++i){
		GridObjectCollection goc = sh.get_grid_objects_in_subset(i);
		out << "\tnum_el_in_blk" << i+1 << " = " << goc.num<Tetrahedron>() << " ;" << endl;
		out << "\tnum_nod_per_el" << i+1 << " = 4 ;" << endl;
	}

	out << "\tnum_qa_rec = 1 ;" << endl;

//	write variables
	out << endl;
	out << "variables:" << endl;
	out << "\tdouble time_whole(time_step) ;" << endl;
	out << "\tint eb_status(num_el_blk) ;" << endl;
	out << "\tint eb_prop1(num_el_blk) ;" << endl;
	out << "\t\teb_prop1:name = \"ID\" ;" << endl;

	for(int i = 0; i < sh.num_subsets(); ++i){
		out << "\tint connect" << i+1
			<< "(num_el_in_blk" << i+1
			<< ", num_nod_per_el" << i+1 << ") ;" << endl;
		out << "\t\tconnect" << i+1 << ":elem_type = \"TETRA4\" ;" << endl;
	}

	out << "\tdouble coord(num_dim, num_nodes) ;" << endl;
	out << "\tchar qa_records(num_qa_rec, four, len_string) ;" << endl;
	out << "\tchar coor_names(num_dim, len_string) ;" << endl;
	out << "\tint elem_map(num_elem) ;" << endl;
	out << "\tint elem_num_map(num_elem) ;" << endl;
	out << "\tint node_num_map(num_nodes) ;" << endl;

	out << "// global attributes:" << endl;
	out << "\t:api_version = 4.01f ;" << endl;
	out << "\t:version = 3.01f ;" << endl;
	out << "\t:floating_point_word_size = " << sizeof(number) << " ;" << endl;
	out << "\t:file_size = 0 ;" << endl;
	out << "\t:title = \"Exported from lib_grid.\" ;" << endl;

//	write data
	out << endl;
	out << "data:" << endl;

	out << "eb_status = ";
	for(int i = 0; i < sh.num_subsets(); ++i){
		out << "1";
		if(i + 1 < sh.num_subsets())
			out << ", ";
	}
	out << " ;" << endl << endl;

	out << "eb_prop1 = ";
	for(int i = 0; i < sh.num_subsets(); ++i){
		out << i+1;
		if(i + 1 < sh.num_subsets())
			out << ", ";
	}
	out << " ;" << endl << endl;

//	write elements
	for(int i = 0; i < sh.num_subsets(); ++i){
	//	get the goc for this subset
		GridObjectCollection goc = sh.get_grid_objects_in_subset(i);

		out << "connect" << i+1 << " =" << endl;
		for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
			for(TetrahedronIterator iter = goc.begin<Tetrahedron>(lvl);
				iter != goc.end<Tetrahedron>(lvl); ++iter)
			{
			//	last comma in each row
				if(iter != goc.begin<Tetrahedron>(lvl))
					out << "," << endl;

				Tetrahedron* tet = *iter;
				out << "  ";
				out << aaInt[tet->vertex(0)] << ", ";
				out << aaInt[tet->vertex(1)] << ", ";
				out << aaInt[tet->vertex(2)] << ", ";
				out << aaInt[tet->vertex(3)];
			}
		}
		out << " ;" << endl << endl;
	}

//	write coords
//	x
	out << "coord =" << endl << " ";
	size_t endlCounter = 1;
	for(VertexIterator iter = grid.vertices_begin();
		iter != grid.vertices_end(); ++iter, ++endlCounter)
	{
		if(endlCounter > 5){
			endlCounter = 1;
			out << endl << " ";
		}

		out << " " << aaPos[*iter].x() << ",";
	}

//	y
	for(VertexIterator iter = grid.vertices_begin();
		iter != grid.vertices_end(); ++iter, ++endlCounter)
	{
		if(endlCounter > 5){
			endlCounter = 1;
			out << endl << " ";
		}
		out << " " << aaPos[*iter].y() << ",";
	}

//	z
	for(VertexIterator iter = grid.vertices_begin();
		iter != grid.vertices_end(); ++iter, ++endlCounter)
	{
		if(iter != grid.vertices_begin()){
			out << ",";
			if(endlCounter > 5){
				endlCounter = 1;
				out << endl << " ";
			}
		}

		out << " " << aaPos[*iter].z();
	}
	out << " ;" << endl << endl;

//	write qa_records
	out << "qa_records =" << endl;
	out << "  \"lib_grid\"," << endl;
	out << "  \"...\"," << endl;
	out << "  \"...\"," << endl;
	out << "  \"...\" ;" << endl;

//	write coor_names
	out << endl;
	out << "coor_names =" << endl;
	out << "  \"x\"," << endl;
	out << "  \"y\"," << endl;
	out << "  \"z\" ;" << endl;

//	write elem_map
	out << endl;
	out << "elem_map = ";
	endlCounter = 1;
	for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter)
	{
		out << i+1;
		if(i+1 < grid.num<Tetrahedron>()){
			out << ", ";

			if(endlCounter > 4){
				endlCounter = 0;
				out << endl << "  ";
			}
		}
	}
	out << " ;" << endl;

//	write elem_num_map
	out << endl;
	out << "elem_num_map = ";
	endlCounter = 1;
	for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter)
	{
		out << i+1;
		if(i+1 < grid.num<Tetrahedron>()){
			out << ", ";

			if(endlCounter > 4){
				endlCounter = 0;
				out << endl << "  ";
			}
		}
	}
	out << " ;" << endl;

//	write node_num_map
	out << endl;
	out << "node_num_map = ";
	endlCounter = 1;
	for(size_t i = 0; i < grid.num<Vertex>(); ++i, ++endlCounter)
	{
		out << i+1;
		if(i+1 < grid.num<Vertex>()){
			out << ", ";

			if(endlCounter > 4){
				endlCounter = 0;
				out << endl << "  ";
			}
		}
	}
	out << " ;" << endl;

//	close object
	out << "}" << endl;
//	remove vertex indices
	grid.detach_from_vertices(aInt);

//	done
	return true;
}
示例#8
0
/******************************************************************************
 * Render the current scene
 * uses the global variables from the parser
 *****************************************************************************/
int ntlWorld::renderScene( void )
{
#ifndef ELBEEM_PLUGIN
	char nrStr[5];														// nr conversion 
	std::ostringstream outfn_conv("");  			// converted ppm with other suffix 
  ntlRenderGlobals *glob;                  	// storage for global rendering parameters 
  myTime_t timeStart,totalStart,timeEnd; 		// measure user running time 
  myTime_t rendStart,rendEnd;            		// measure user rendering time 
  glob = mpGlob;

	// deactivate for all with index!=0 
	if((glob_mpactive)&&(glob_mpindex>0)) return(0);

	/* check if picture already exists... */
	if(!glob->getSingleFrameMode() ) {
		snprintf(nrStr, 5, "%04d", glob->getAniCount() );

		if(glob_mpactive) {
			outfn_conv  << glob->getOutFilename() <<"_"<<glob_mpindex<<"_" << nrStr << ".png"; /// DEBUG!
		} else {
			// ORG
			outfn_conv  << glob->getOutFilename() <<"_" << nrStr << ".png";
		}
		
		//if((mpGlob->getDisplayMode() == DM_RAY)&&(mpGlob->getFrameSkip())) {
		if(mpGlob->getFrameSkip()) {
			struct stat statBuf;
			if(stat(outfn_conv.str().c_str(),&statBuf) == 0) {
				errorOut("ntlWorld::renderscene Warning: file "<<outfn_conv.str()<<" already exists - skipping frame..."); 
				glob->setAniCount( glob->getAniCount() +1 );
				return(2);
			}
		} // RAY mode
	} else {
		// single frame rendering, overwrite if necessary...
		outfn_conv << glob->getSingleFrameFilename();
	}

  /* start program */
	timeStart = getTime();

	/* build scene geometry, calls buildScene(t,false) */
	glob->getRenderScene()->prepareScene(mSimulationTime);

  /* start program */
	totalStart = getTime();


	/* view parameters are currently not animated */
	/* calculate rays through projection plane */
	ntlVec3Gfx direction = glob->getLookat() - glob->getEye();
	/* calculate width of screen using perpendicular triangle diven by
	 * viewing direction and screen plane */
	gfxReal screenWidth = norm(direction)*tan( (glob->getFovy()*0.5/180.0)*M_PI );

	/* calculate vector orthogonal to up and viewing direction */
	ntlVec3Gfx upVec = glob->getUpVec();
	ntlVec3Gfx rightVec( cross(upVec,direction) );
	normalize(rightVec);

	/* calculate screen plane up vector, perpendicular to viewdir and right vec */
	upVec = ntlVec3Gfx( cross(rightVec,direction) );
	normalize(upVec);

	/* check if vectors are valid */
	if( (equal(upVec,ntlVec3Gfx(0.0))) || (equal(rightVec,ntlVec3Gfx(0.0))) ) {
		errMsg("ntlWorld::renderScene","Invalid viewpoint vectors! up="<<upVec<<" right="<<rightVec);
		return(1);
	}

	/* length from center to border of screen plane */
	rightVec *= (screenWidth*glob->getAspect() * -1.0);
	upVec *= (screenWidth * -1.0);

	/* screen traversal variables */
	ntlVec3Gfx screenPos;                          /* current position on virtual screen */
	int Xres = glob->getResX();                  /* X resolution */
	int Yres = glob->getResY();                  /* Y resolution */
	ntlVec3Gfx rightStep = (rightVec/(Xres/2.0));  /* one step right for a pixel */
	ntlVec3Gfx upStep    = (upVec/(Yres/2.0));     /* one step up for a pixel */
    

	/* anti alias init */
	char  showAAPic = 0;
	int   aaDepth = glob->getAADepth();
	int   aaLength;
	if(aaDepth>=0) aaLength = (2<<aaDepth);
	else           aaLength = 0;
	float aaSensRed   = 0.1;
	float aaSensGreen = 0.1;
	float aaSensBlue  = 0.1;
	int   aaArrayX = aaLength*Xres+1;
	int   aaArrayY = ( aaLength+1 );
	ntlColor *aaCol = new ntlColor[ aaArrayX*aaArrayY ];
	char  *aaUse = new char[ aaArrayX*aaArrayY ];

	/* picture storage */
	int picX = Xres;
	int picY = Yres;
	if(showAAPic) {
		picX = Xres *aaLength+1;
		picY = Yres *aaLength+1;
	}
	ntlColor *finalPic = new ntlColor[picX * picY];


	/* reset picture vars */
	for(int j=0;j<aaArrayY;j++) {
		for(int i=0;i<aaArrayX;i++) {
			aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0);
			aaUse[j*aaArrayX+i] = 0;
		}
	}
	for(int j=0;j<picY;j++) {
		for(int i=0;i<picX;i++) {
			finalPic[j*picX+i] = ntlColor(0.0, 0.0, 0.0);
		}
	}

	/* loop over all y lines in screen, from bottom to top because
	 * ppm format wants 0,0 top left */
	rendStart = getTime();
	glob->setCounterShades(0);
	glob->setCounterSceneInter(0);
	for (int scanline=Yres ; scanline > 0 ; --scanline) {
    
		debugOutInter( "ntlWorld::renderScene: Line "<<scanline<<
								 " ("<< ((Yres-scanline)*100/Yres) <<"%) ", 2, 2000 );
		screenPos = glob->getLookat() + upVec*((2.0*scanline-Yres)/Yres)
			- rightVec;

		/* loop over all pixels in line */
		for (int sx=0 ; sx < Xres ; ++sx) {

			if((sx==glob->getDebugPixelX())&&(scanline==(Yres-glob->getDebugPixelY()) )) {
				// DEBUG!!!
				glob->setDebugOut(10);
			} else glob->setDebugOut(0);
			
			/* compute ray from eye through current pixel into scene... */
			ntlColor col;
			if(aaDepth<0) {
				ntlVec3Gfx dir(screenPos - glob->getEye());
				ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob );

				/* ...and trace it */
				col = the_ray.shade();
			} else {
				/* anti alias */
				int ai,aj;                   /* position in grid */
				int aOrg = sx*aaLength;      /* grid offset x */
				int currStep = aaLength;     /* step size */
				char colDiff = 1;            /* do colors still differ too much? */
				ntlColor minCol,maxCol;         /* minimum and maximum Color Values */
				minCol = ntlColor(1.0,1.0,1.0);
				maxCol = ntlColor(0.0,0.0,0.0);

				while((colDiff) && (currStep>0)) {
					colDiff = 0;
	    
					for(aj = 0;aj<=aaLength;aj+= currStep) {
						for(ai = 0;ai<=aaLength;ai+= currStep) {

							/* shade pixel if not done */
							if(aaUse[aj*aaArrayX +ai +aOrg] == 0) {
								aaUse[aj*aaArrayX +ai +aOrg] = 1;
								ntlVec3Gfx aaPos( screenPos +
																(rightStep * (ai- aaLength/2)/(gfxReal)aaLength ) +
																(upStep    * (aj- aaLength/2)/(gfxReal)aaLength ) );

								ntlVec3Gfx dir(aaPos - glob->getEye());
								ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob );

								/* ...and trace it */
								ntlColor newCol= the_ray.shade();
								aaCol[aj*aaArrayX +ai +aOrg]= newCol;
							} /* not used? */

						}
					}

					/* check color differences */
					for(aj = 0;aj<aaLength;aj+= currStep) {
						for(ai = 0;ai<aaLength;ai+= currStep) {

							char thisColDiff = 0;
							if( 
								 (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - 
											 aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) ||
								 (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - 
											 aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) ||
								 (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - 
											 aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) {
								thisColDiff = 1;
							} else
								if( 
									 (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - 
												 aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][0])> aaSensRed ) ||
									 (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - 
												 aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][1])> aaSensGreen ) ||
									 (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - 
												 aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][2])> aaSensBlue ) ) {
									thisColDiff = 1;
								} else
									if( 
										 (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - 
													 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) ||
										 (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - 
													 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) ||
										 (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - 
													 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) {
										thisColDiff = 1;
									} 

							//colDiff =1;
							if(thisColDiff) {
								/* set diff flag */
								colDiff = thisColDiff;
								for(int bj=aj;bj<=aj+currStep;bj++) {
									for(int bi=ai;bi<=ai+currStep;bi++) {
										if(aaUse[bj*aaArrayX +bi +aOrg]==2) {
											//if(showAAPic) 
											aaUse[bj*aaArrayX +bi +aOrg] = 0;
										}
									}
								}
							} else {
								/* set all values */
								ntlColor avgCol = (
																	 aaCol[(aj+0       )*aaArrayX +(ai+0       ) +aOrg] +
																	 aaCol[(aj+0       )*aaArrayX +(ai+currStep) +aOrg] +
																	 aaCol[(aj+currStep)*aaArrayX +(ai+0       ) +aOrg] +
																	 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg] ) *0.25;
								for(int bj=aj;bj<=aj+currStep;bj++) {
									for(int bi=ai;bi<=ai+currStep;bi++) {
										if(aaUse[bj*aaArrayX +bi +aOrg]==0) {
											aaCol[bj*aaArrayX +bi +aOrg] = avgCol; 
											aaUse[bj*aaArrayX +bi +aOrg] = 2;
										}
									}
								}
							} /* smaller values set */

						}
					}

					/* half step size */
					currStep /= 2;

				} /* repeat until diff not too big */

				/* get average color */
				gfxReal colNum = 0.0;
				col = ntlColor(0.0, 0.0, 0.0);
				for(aj = 0;aj<=aaLength;aj++) {
					for(ai = 0;ai<=aaLength;ai++) {
						col += aaCol[aj*aaArrayX +ai +aOrg];
						colNum += 1.0;
					}
				}
				col /= colNum;

			}

		  /* mark pixels with debugging */
			if( glob->getDebugOut() > 0) col = ntlColor(0,1,0);

			/* store pixel */
			if(!showAAPic) {
				finalPic[(scanline-1)*picX+sx] = col; 
			}
			screenPos +=  rightStep;

		} /* foreach x */

		/* init aa array */
		if(showAAPic) {
			for(int j=0;j<=aaArrayY-1;j++) {
				for(int i=0;i<=aaArrayX-1;i++) {
					if(aaUse[j*aaArrayX +i]==1) finalPic[((scanline-1)*aaLength +j)*picX+i][0] = 1.0;
				}
			}
		}

		for(int i=0;i<aaArrayX;i++) {
			aaCol[(aaArrayY-1)*aaArrayX+i] = aaCol[0*aaArrayX+i];
			aaUse[(aaArrayY-1)*aaArrayX+i] = aaUse[0*aaArrayX+i];
		}
		for(int j=0;j<aaArrayY-1;j++) {
			for(int i=0;i<aaArrayX;i++) {
				aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0);
				aaUse[j*aaArrayX+i] = 0;
			}
		}

	} /* foreach y */
	rendEnd = getTime();


	/* write png file */
	{
		int w = picX;
		int h = picY;

		unsigned rowbytes = w*4;
		unsigned char *screenbuf, **rows;
		screenbuf = (unsigned char*)malloc( h*rowbytes );
		rows = (unsigned char**)malloc( h*sizeof(unsigned char*) );
		unsigned char *filler = screenbuf;

		// cutoff color values 0..1
		for(int j=0;j<h;j++) {
			for(int i=0;i<w;i++) {
				ntlColor col = finalPic[j*w+i];
				for (unsigned int cc=0; cc<3; cc++) {
					if(col[cc] <= 0.0) col[cc] = 0.0;
					if(col[cc] >= 1.0) col[cc] = 1.0;
				}
				*filler = (unsigned char)( col[0]*255.0 ); 
				filler++;
				*filler = (unsigned char)( col[1]*255.0 ); 
				filler++;
				*filler = (unsigned char)( col[2]*255.0 ); 
				filler++;
				*filler = (unsigned char)( 255.0 ); 
				filler++; // alpha channel
			}
		}

		for(int i = 0; i < h; i++) rows[i] = &screenbuf[ (h - i - 1)*rowbytes ];
		writePng(outfn_conv.str().c_str(), rows, w, h);
	}


	// next frame 
	glob->setAniCount( glob->getAniCount() +1 );

	// done 
	timeEnd = getTime();

	char resout[1024];
	snprintf(resout,1024, "NTL Done %s, frame %d/%d (took %s scene, %s raytracing, %s total, %d shades, %d i.s.'s)!\n", 
				 outfn_conv.str().c_str(), (glob->getAniCount()), (glob->getAniFrames()+1),
				 getTimeString(totalStart-timeStart).c_str(), getTimeString(rendEnd-rendStart).c_str(), getTimeString(timeEnd-timeStart).c_str(),
				 glob->getCounterShades(),
				 glob->getCounterSceneInter() );
	debMsgStd("ntlWorld::renderScene",DM_MSG, resout, 1 );

	/* clean stuff up */
	delete [] aaCol;
	delete [] aaUse;
	delete [] finalPic;
	glob->getRenderScene()->cleanupScene();

	if(mpGlob->getSingleFrameMode() ) {
		debMsgStd("ntlWorld::renderScene",DM_NOTIFY, "Single frame mode done...", 1 );
		return 1;
	}
#endif // ELBEEM_PLUGIN
	return 0;
}
bool TriangleFill_SweepLine(Grid& grid, TIterator edgesBegin,
							TIterator edgesEnd, APosition& aPosVRT,
							AInt& aIntVRT,
							SubsetHandler* pSH,
							int newSubsetIndex)
{
	if(!grid.has_vertex_attachment(aPosVRT)){
		UG_LOG("position attachment missing in TriangleFill_SweepLine");
		return false;
	}

	if(!grid.has_vertex_attachment(aIntVRT)){
		UG_LOG("int attachment missing in TriangleFill_SweepLine");
		return false;
	}

	Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPosVRT);
	Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aIntVRT);

//	set up the vertex and edge arrays and build some additional
//	information that is required when it comes to building the triangles.
	std::vector<Vertex*> vrtPtrs;
	std::vector<vector3> vrts;
	std::vector<int>	edges;

	grid.begin_marking();
	for(TIterator iter = edgesBegin; iter != edgesEnd; ++iter)
	{
		Edge* e = *iter;

		for(size_t i = 0; i < 2; ++i){
			Vertex* vrt = e->vertex(i);
			if(!grid.is_marked(vrt)){
				aaInt[vrt] = (int)vrts.size();
				vrts.push_back(aaPos[vrt]);
				//vrts.push_back(vector2(aaPos[vrt].x(), aaPos[vrt].y()));
				vrtPtrs.push_back(vrt);
				grid.mark(vrt);
			}

			edges.push_back(aaInt[vrt]);
		}
	}
	grid.end_marking();

//	now call the original implementation
	size_t numInitialEdges = edges.size();
	std::vector<int> faces;
	if(TriangleFill_SweepLine(faces, vrts, edges)){

	//	now create the triangles
		for(size_t i = 0; i < faces.size(); i+=3){
			Triangle* tri = *grid.create<Triangle>(TriangleDescriptor(vrtPtrs[faces[i]],
																	  vrtPtrs[faces[i + 1]],
																	  vrtPtrs[faces[i + 2]]));
			if(pSH){
				pSH->assign_subset(tri, newSubsetIndex);
			}
		}

		return true;
	}

	else{
	//DEBUG ONLY
	//	create edges
		for(size_t i = numInitialEdges; i < edges.size(); i+=2){
			Edge* e = *grid.create<RegularEdge>(EdgeDescriptor(vrtPtrs[edges[i]], vrtPtrs[edges[i+1]]));
			if(pSH){
				pSH->assign_subset(e, newSubsetIndex);
			}
		}
	}

	return false;
}
示例#10
0
bool AdaptSurfaceGridToCylinder(Selector& selOut, Grid& grid,
                                Vertex* vrtCenter, const vector3& normal,
                                number radius, number rimSnapThreshold,  AInt& aInt,
                                APosition& aPos)
{
    if(!grid.has_vertex_attachment(aPos)) {
        UG_THROW("Position attachment required!");
    }

    Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);

    if(rimSnapThreshold < 0)
        rimSnapThreshold = 0;

    if(rimSnapThreshold > (radius - SMALL))
        rimSnapThreshold = radius - SMALL;

    const number smallRadius = radius - rimSnapThreshold;
    const number smallRadiusSq = smallRadius * smallRadius;
    const number largeRadius = radius + rimSnapThreshold;
    const number largeRadiusSq = largeRadius * largeRadius;

//	the cylinder geometry
    vector3 axis;
    VecNormalize(axis, normal);
    vector3 center = aaPos[vrtCenter];

//	recursively select all vertices in the cylinder which can be reached from a
//	selected vertex by following an edge. Start with the given one.
//	We'll also select edges which connect inner with outer vertices. Note that
//	some vertices are considered rim-vertices (those with a distance between
//	smallRadius and largeRadius). Those are neither considered inner nor outer.
    Selector& sel = selOut;
    sel.clear();
    sel.select(vrtCenter);

    stack<Vertex*> vrtStack;
    vrtStack.push(vrtCenter);

    Grid::edge_traits::secure_container edges;
    Grid::face_traits::secure_container faces;
    vector<Quadrilateral*> quads;

    while(!vrtStack.empty()) {
        Vertex* curVrt = vrtStack.top();
        vrtStack.pop();

        //	we have to convert associated quadrilaterals to triangles.
        //	Be careful not to alter the array of associated elements while we iterate
        //	over it...
        quads.clear();
        grid.associated_elements(faces, curVrt);
        for(size_t i = 0; i < faces.size(); ++i) {
            if(faces[i]->num_vertices() == 4) {
                Quadrilateral* q = dynamic_cast<Quadrilateral*>(faces[i]);
                if(q)
                    quads.push_back(q);
            }
        }

        for(size_t i = 0; i < quads.size(); ++i) {
            Triangulate(grid, quads[i], &aaPos);
        }

        //	now check whether edges leave the cylinder and mark them accordingly.
        //	Perform projection of vertices to the cylinder rim for vertices which
        //	lie in the threshold area.
        grid.associated_elements(edges, curVrt);

        for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge) {
            Edge* e = edges[i_edge];
            Vertex* vrt = GetConnectedVertex(e, curVrt);

            if(sel.is_selected(vrt))
                continue;

            vector3 p = aaPos[vrt];
            vector3 proj;
            ProjectPointToRay(proj, p, center, axis);
            number distSq = VecDistanceSq(p, proj);

            if(distSq < smallRadiusSq) {
                sel.select(vrt);
                vrtStack.push(vrt);
            }
            else if(distSq < largeRadiusSq) {
                sel.select(vrt);
                //	cut the ray from center through p with the cylinder hull to calculate
                //	the new position of vrt.
                vector3 dir;
                VecSubtract(dir, p, center);
                number t0, t1;
                if(RayCylinderIntersection(t0, t1, center, dir, center, axis, radius))
                    VecScaleAdd(aaPos[vrt], 1., center, t1, dir);
            }
            else {
                //	the edge will be refined later on
                sel.select(e);
            }
        }
    }

//	refine selected edges and use a special refinement callback, which places
//	new vertices on edges which intersect a cylinder on the cylinders hull.
    CylinderCutProjector refCallback(MakeGeometry3d(grid, aPos),
                                     center, axis, radius);
    Refine(grid, sel, aInt, &refCallback);

//	finally select all triangles which lie in the cylinder
    sel.clear();
    vrtStack.push(vrtCenter);
    sel.select(vrtCenter);

    while(!vrtStack.empty()) {
        Vertex* curVrt = vrtStack.top();
        vrtStack.pop();
        grid.associated_elements(faces, curVrt);

        for(size_t i_face = 0; i_face < faces.size(); ++i_face) {
            Face* f = faces[i_face];
            if(sel.is_selected(f))
                continue;

            sel.select(f);

            for(size_t i = 0; i < f->num_vertices(); ++i) {
                Vertex* vrt = f->vertex(i);
                if(!sel.is_selected(vrt)) {
                    number dist = DistancePointToRay(aaPos[vrt], center, axis);
                    if(dist < (radius - SMALL)) {
                        sel.select(vrt);
                        vrtStack.push(vrt);
                    }
                }
            }
        }
    }

    sel.clear<Vertex>();

    return true;
}