| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
 | 
					
						
							|  |  |  |  *  \ingroup freestyle | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #include "BlenderFileLoader.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-09 23:25:02 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 17:12:38 +09:00
										 |  |  | #include <sstream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-09 00:46:49 +00:00
										 |  |  | namespace Freestyle { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | BlenderFileLoader::BlenderFileLoader(Render *re, SceneRenderLayer *srl) | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	_re = re; | 
					
						
							| 
									
										
											  
											
												SUMMARY:
Freestyle's pipeline is now fully controllable at the layer level. It can be used:
 - in any render layer
 - with as many style modules per layer
DETAILS:
Freestyle usage has not changed:
  - all the configuration happens in the "Freestyle" render panel, after it is enabled in the "Output" panel with the 'Freestyle' toggle.
  - each render layer can choose to render Freestyle strokes by togglingo on 'FrSt' (in the "Render Layers" panel)
  - it is fully compatible with compositor nodes
In the "Freestyle" panel, a render layer is selected via the menu list next to the "Render Layer:" label. The options displayed below are those of the currently selected render layer (and are not global to all render layers, as was previously the case).
Style modules are added by pressing the lower button "Add style module". Once added, the following operations are possible:
- deletion (cross)
- reordering (up/down arrows)
- toggling of display (check)
The order of the style modules follows Freestyle's original convention: the modules in the list from top to bottom are respectively the first to the last composited in the render layer. For example, if the module list is "contour" followed by "cartoon", the "cartoon" strokes are rendered on top of the "contour" strokes.
The "Freestyle" panel is constantly synchronized with the "Render Layers" panel: if render layers are added, deleted or toggled off display, Freestyle will take note of the changes.
The current pipeline works as follows:
----------------------------------------------------------------------------------------------
for every scene that is being rendered
	if Freestyle is enabled globally
	
		Freestyle is initialized
		camera and view settings are transferred from Blender to Freestyle
		
		for every render layer
			if: - layer is enabled 
			    - layer enabled Freestyle
			    - the number of displayed style modules is non-zero
				
				canvas is cleared
				geometry is transferred from Blender to Freestyle
				settings are fixed for current iteration
				view map is calculated
				
				strokes are computed in the canvas (based on view map and style modules)
				strokes are rendered in separate Blender scene
				
				scene is composited in current layer
----------------------------------------------------------------------------------------------
A number of changes were made on the codebase:
- the rendering interface between Freestyle and Blender was simplified. The following naming convention was used: functions that are called from within Blender pipeline are prefixed with 'FRS_', while the variables are prefixed with 'freestyle_'
- Freestyle data structures that were put in Blender's render pipeline were removed
- Freestyle cleans up its data structures on Blender exit and shouldn't leak memory
- to ease the configuration in the "Freestyle" panel, a centralized configuration data structure was used and can be easily extended
LIMITATIONS
Even though the current commit is stable and achieves the intended result, it is not as efficient as it could be:
- the canvas and the style modules are at cleared at each layer-level render
- geometry is reloaded at each frame and is duplicated across render layers
This revision clarifies my understanding of the future role of the view map in the compositor. Unfortunately, contrary to what the original proposal said, it is impossible to provide the view map as a render pass because render passes are defined (RE_pipeline.h) as raw floating-point rects. We will have to determine whether or not to extend the notion of render pass to fully integrate the view map in the compositor.
											
										 
											2009-04-07 18:38:23 +00:00
										 |  |  | 	_srl = srl; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	_Scene = NULL; | 
					
						
							|  |  |  | 	_numFacesRead = 0; | 
					
						
							|  |  |  | 	_minEdgeSize = DBL_MAX; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 	_smooth = (srl->freestyleConfig.flags & FREESTYLE_FACE_SMOOTHNESS_FLAG) != 0; | 
					
						
							| 
									
										
										
										
											2014-06-24 17:12:38 +09:00
										 |  |  | 	_pRenderMonitor = NULL; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | BlenderFileLoader::~BlenderFileLoader() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	_Scene = NULL; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | NodeGroup *BlenderFileLoader::Load() | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	ObjectInstanceRen *obi; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 	if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 		cout << "\n===  Importing triangular meshes into Blender  ===" << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-08-08 08:25:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-10 14:08:59 +00:00
										 |  |  | 	// creation of the scene root node
 | 
					
						
							|  |  |  | 	_Scene = new NodeGroup; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	_viewplane_left =   _re->viewplane.xmin; | 
					
						
							|  |  |  | 	_viewplane_right =  _re->viewplane.xmax; | 
					
						
							|  |  |  | 	_viewplane_bottom = _re->viewplane.ymin; | 
					
						
							|  |  |  | 	_viewplane_top =    _re->viewplane.ymax; | 
					
						
							| 
									
										
										
										
											2013-07-09 23:25:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if ((_re->r.scemode & R_VIEWPORT_PREVIEW) && (_re->r.mode & R_ORTHO)) { | 
					
						
							|  |  |  | 		// Adjust clipping start/end and set up a Z offset when the viewport preview
 | 
					
						
							|  |  |  | 		// is used with the orthographic view.  In this case, _re->clipsta is negative,
 | 
					
						
							|  |  |  | 		// while Freestyle assumes that imported mesh data are in the camera coordinate
 | 
					
						
							|  |  |  | 		// system with the view point located at origin [bug #36009].
 | 
					
						
							|  |  |  | 		BLI_assert(_re->clipsta < 0.f); | 
					
						
							|  |  |  | 		_z_near = -0.001f; | 
					
						
							|  |  |  | 		_z_offset = _re->clipsta + _z_near; | 
					
						
							|  |  |  | 		_z_far = -_re->clipend + _z_offset; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		_z_near = -_re->clipsta; | 
					
						
							|  |  |  | 		_z_far = -_re->clipend; | 
					
						
							|  |  |  | 		_z_offset = 0.f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-10 14:08:59 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 	if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 		cout << "Frustum: l " << _viewplane_left << " r " << _viewplane_right | 
					
						
							|  |  |  | 		     << " b " << _viewplane_bottom << " t " << _viewplane_top | 
					
						
							|  |  |  | 		     << " n " << _z_near << " f " << _z_far << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-10 14:08:59 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int id = 0; | 
					
						
							| 
									
										
										
										
											2014-06-24 17:12:38 +09:00
										 |  |  | 	unsigned cnt = 1; | 
					
						
							|  |  |  | 	unsigned cntStep = (unsigned)ceil(0.01f * _re->totinstance); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	for (obi = (ObjectInstanceRen *)_re->instancetable.first; obi; obi = obi->next) { | 
					
						
							| 
									
										
										
										
											2014-06-24 17:12:38 +09:00
										 |  |  | 		if (_pRenderMonitor) { | 
					
						
							|  |  |  | 			if (_pRenderMonitor->testBreak()) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			if (cnt % cntStep == 0) { | 
					
						
							|  |  |  | 				stringstream ss; | 
					
						
							|  |  |  | 				ss << "Freestyle: Mesh loading " << (100 * cnt / _re->totinstance) << "%"; | 
					
						
							|  |  |  | 				_pRenderMonitor->setInfo(ss.str()); | 
					
						
							|  |  |  | 				_pRenderMonitor->progress((float)cnt / _re->totinstance); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			cnt++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-11 22:20:46 +00:00
										 |  |  | 		if (!(obi->lay & _srl->lay)) | 
					
						
							| 
									
										
										
										
											2009-03-02 03:30:59 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 		char *name = obi->ob->id.name; | 
					
						
							| 
									
										
										
										
											2013-03-16 16:41:12 +00:00
										 |  |  | 		//printf("%c%c:%s\n", name[0], name[1], name+2);
 | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 		//print_m4("obi->mat", obi->mat);
 | 
					
						
							| 
									
										
										
										
											2009-03-02 03:30:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		if (obi->obr->totvlak > 0) { | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 			insertShapeNode(obi, ++id); | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 			cout << "Warning: " << (name + 2) << " is not a vlak-based object (ignored)" << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	// Return the built scene.
 | 
					
						
							| 
									
										
										
										
											2010-01-10 14:08:59 +00:00
										 |  |  | 	return _Scene; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | #define CLIPPED_BY_NEAR -1
 | 
					
						
							|  |  |  | #define NOT_CLIPPED      0
 | 
					
						
							|  |  |  | #define CLIPPED_BY_FAR   1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // check if each vertex of a triangle (V1, V2, V3) is clipped by the near/far plane
 | 
					
						
							|  |  |  | // and calculate the number of triangles to be generated by clipping
 | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | int BlenderFileLoader::countClippedFaces(float v1[3], float v2[3], float v3[3], int clip[3]) | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 	float *v[3]; | 
					
						
							| 
									
										
										
										
											2013-01-18 02:13:36 +00:00
										 |  |  | 	int numClipped, sum, numTris = 0; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	v[0] = v1; | 
					
						
							|  |  |  | 	v[1] = v2; | 
					
						
							|  |  |  | 	v[2] = v3; | 
					
						
							|  |  |  | 	numClipped = sum = 0; | 
					
						
							|  |  |  | 	for (int i = 0; i < 3; i++) { | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 		if (v[i][2] > _z_near) { | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			clip[i] = CLIPPED_BY_NEAR; | 
					
						
							|  |  |  | 			numClipped++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (v[i][2] < _z_far) { | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			clip[i] = CLIPPED_BY_FAR; | 
					
						
							|  |  |  | 			numClipped++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			clip[i] = NOT_CLIPPED; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 		if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 			printf("%d %s\n", i, (clip[i] == NOT_CLIPPED) ? "not" : (clip[i] == CLIPPED_BY_NEAR) ? "near" : "far"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 		sum += clip[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	switch (numClipped) { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							|  |  |  | 		numTris = 1; // triangle
 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: | 
					
						
							|  |  |  | 		numTris = 2; // tetragon
 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 2: | 
					
						
							|  |  |  | 		if (sum == 0) | 
					
						
							|  |  |  | 			numTris = 3; // pentagon
 | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			numTris = 1; // triangle
 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 3: | 
					
						
							|  |  |  | 		if (sum == 3 || sum == -3) | 
					
						
							|  |  |  | 			numTris = 0; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			numTris = 2; // tetragon
 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return numTris; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // find the intersection point C between the line segment from V1 to V2 and
 | 
					
						
							|  |  |  | // a clipping plane at depth Z (i.e., the Z component of C is known, while
 | 
					
						
							|  |  |  | // the X and Y components are unknown).
 | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | void BlenderFileLoader::clipLine(float v1[3], float v2[3], float c[3], float z) | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-20 19:03:52 +00:00
										 |  |  | 	// Order v1 and v2 by Z values to make sure that clipLine(P, Q, c, z)
 | 
					
						
							|  |  |  | 	// and clipLine(Q, P, c, z) gives exactly the same numerical result.
 | 
					
						
							|  |  |  | 	float *p, *q; | 
					
						
							|  |  |  | 	if (v1[2] < v2[2]) { | 
					
						
							|  |  |  | 		p = v1; | 
					
						
							|  |  |  | 		q = v2; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2011-11-20 19:03:52 +00:00
										 |  |  | 		p = v2; | 
					
						
							|  |  |  | 		q = v1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	double d[3]; | 
					
						
							|  |  |  | 	for (int i = 0; i < 3; i++) | 
					
						
							| 
									
										
										
										
											2011-11-20 19:03:52 +00:00
										 |  |  | 		d[i] = q[i] - p[i]; | 
					
						
							|  |  |  | 	double t = (z - p[2]) / d[2]; | 
					
						
							|  |  |  | 	c[0] = p[0] + t * d[0]; | 
					
						
							|  |  |  | 	c[1] = p[1] + t * d[1]; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	c[2] = z; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // clip the triangle (V1, V2, V3) by the near and far clipping plane and
 | 
					
						
							|  |  |  | // obtain a set of vertices after the clipping.  The number of vertices
 | 
					
						
							|  |  |  | // is at most 5.
 | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3], | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  |                                      float triNormals[][3], float n1[3], float n2[3], float n3[3], | 
					
						
							|  |  |  |                                      bool edgeMarks[], bool em1, bool em2, bool em3, int clip[3]) | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 	float *v[3], *n[3]; | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 	bool em[3]; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	int i, j, k; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 	v[0] = v1; n[0] = n1; | 
					
						
							|  |  |  | 	v[1] = v2; n[1] = n2; | 
					
						
							|  |  |  | 	v[2] = v3; n[2] = n3; | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 	em[0] = em1; /* edge mark of the edge between v1 and v2 */ | 
					
						
							|  |  |  | 	em[1] = em2; /* edge mark of the edge between v2 and v3 */ | 
					
						
							|  |  |  | 	em[2] = em3; /* edge mark of the edge between v3 and v1 */ | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	k = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							|  |  |  | 		j = (i + 1) % 3; | 
					
						
							|  |  |  | 		if (clip[i] == NOT_CLIPPED) { | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 			copy_v3_v3(triCoords[k], v[i]); | 
					
						
							|  |  |  | 			copy_v3_v3(triNormals[k], n[i]); | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 			edgeMarks[k] = em[i]; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 			k++; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			if (clip[j] != NOT_CLIPPED) { | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); | 
					
						
							|  |  |  | 				copy_v3_v3(triNormals[k], n[j]); | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 				edgeMarks[k] = false; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				k++; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (clip[i] != clip[j]) { | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			if (clip[j] == NOT_CLIPPED) { | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); | 
					
						
							|  |  |  | 				copy_v3_v3(triNormals[k], n[i]); | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 				edgeMarks[k] = em[i]; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				k++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); | 
					
						
							|  |  |  | 				copy_v3_v3(triNormals[k], n[i]); | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 				edgeMarks[k] = em[i]; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				k++; | 
					
						
							|  |  |  | 				clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); | 
					
						
							|  |  |  | 				copy_v3_v3(triNormals[k], n[j]); | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 				edgeMarks[k] = false; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 				k++; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-07-09 23:25:02 +00:00
										 |  |  | 	BLI_assert(k == 2 + numTris); | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3], | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  |                                     float n1[3], float n2[3], float n3[3], | 
					
						
							|  |  |  |                                     bool fm, bool em1, bool em2, bool em3) | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 	float *fv[3], *fn[3], len; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	unsigned int i, j; | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 	IndexedFaceSet::FaceEdgeMark marks = 0; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// initialize the bounding box by the first vertex
 | 
					
						
							|  |  |  | 	if (ls->currentIndex == 0) { | 
					
						
							|  |  |  | 		copy_v3_v3(ls->minBBox, v1); | 
					
						
							|  |  |  | 		copy_v3_v3(ls->maxBBox, v1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 	fv[0] = v1; fn[0] = n1; | 
					
						
							|  |  |  | 	fv[1] = v2; fn[1] = n2; | 
					
						
							|  |  |  | 	fv[2] = v3; fn[2] = n3; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		copy_v3_v3(ls->pv, fv[i]); | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 		copy_v3_v3(ls->pn, fn[i]); | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// update the bounding box
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		for (j = 0; j < 3; j++) { | 
					
						
							|  |  |  | 			if (ls->minBBox[j] > ls->pv[j]) | 
					
						
							|  |  |  | 				ls->minBBox[j] = ls->pv[j]; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			if (ls->maxBBox[j] < ls->pv[j]) | 
					
						
							|  |  |  | 				ls->maxBBox[j] = ls->pv[j]; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		len = len_v3v3(fv[i], fv[(i + 1) % 3]); | 
					
						
							|  |  |  | 		if (_minEdgeSize > len) | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			_minEdgeSize = len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 		*ls->pvi = ls->currentIndex; | 
					
						
							|  |  |  | 		*ls->pni = ls->currentIndex; | 
					
						
							|  |  |  | 		*ls->pmi = ls->currentMIndex; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		ls->currentIndex += 3; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 		ls->pv += 3; | 
					
						
							|  |  |  | 		ls->pn += 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ls->pvi++; | 
					
						
							|  |  |  | 		ls->pni++; | 
					
						
							|  |  |  | 		ls->pmi++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (fm) | 
					
						
							|  |  |  | 		marks |= IndexedFaceSet::FACE_MARK; | 
					
						
							|  |  |  | 	if (em1) | 
					
						
							|  |  |  | 		marks |= IndexedFaceSet::EDGE_MARK_V1V2; | 
					
						
							|  |  |  | 	if (em2) | 
					
						
							|  |  |  | 		marks |= IndexedFaceSet::EDGE_MARK_V2V3; | 
					
						
							|  |  |  | 	if (em3) | 
					
						
							|  |  |  | 		marks |= IndexedFaceSet::EDGE_MARK_V3V1; | 
					
						
							|  |  |  | 	*(ls->pm++) = marks; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | // With A, B and P indicating the three vertices of a given triangle, returns:
 | 
					
						
							|  |  |  | // 1 if points A and B are in the same position in the 3D space;
 | 
					
						
							|  |  |  | // 2 if the distance between point P and line segment AB is zero; and
 | 
					
						
							|  |  |  | // zero otherwise.
 | 
					
						
							|  |  |  | int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3[3]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-12 00:18:27 +00:00
										 |  |  | 	const float eps = 1.0e-6; | 
					
						
							|  |  |  | 	const float eps_sq = eps * eps; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 	float area = area_tri_v3(v1, v2, v3); | 
					
						
							|  |  |  | 	bool verbose = (area < 1.0e-6); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (equals_v3v3(v1, v2) || equals_v3v3(v2, v3) || equals_v3v3(v1, v3)) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		if (verbose && G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			printf("BlenderFileLoader::testDegenerateTriangle = 1\n"); | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-07-12 00:18:27 +00:00
										 |  |  | 	if (dist_squared_to_line_segment_v3(v1, v2, v3) < eps_sq || | 
					
						
							|  |  |  | 	    dist_squared_to_line_segment_v3(v2, v1, v3) < eps_sq || | 
					
						
							|  |  |  | 	    dist_squared_to_line_segment_v3(v3, v1, v2) < eps_sq) | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		if (verbose && G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			printf("BlenderFileLoader::testDegenerateTriangle = 2\n"); | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 		return 2; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 	if (verbose && G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		printf("BlenderFileLoader::testDegenerateTriangle = 0\n"); | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks if edge rotation (if necessary) can prevent the given quad from
 | 
					
						
							|  |  |  | // being decomposed into a degenerate triangle
 | 
					
						
							|  |  |  | bool BlenderFileLoader::testEdgeRotation(float v1[3], float v2[3], float v3[3], float v4[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (testDegenerateTriangle(v1, v2, v3) == 2 || testDegenerateTriangle(v1, v3, v4) == 2) { | 
					
						
							|  |  |  | 		if (testDegenerateTriangle(v1, v2, v4) == 2 || testDegenerateTriangle(v2, v3, v4) == 2) { | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 			if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 				printf("BlenderFileLoader::testEdgeRotation: edge rotation is unsuccessful.\n"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-03-03 12:01:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 	ObjectRen *obr = obi->obr; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	char *name = obi->ob->id.name + 2; | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:36:12 +00:00
										 |  |  | 	// We parse vlak nodes and count the number of faces after the clipping by
 | 
					
						
							|  |  |  | 	// the near and far view planes is applied (Note: mesh vertices are in the
 | 
					
						
							|  |  |  | 	// camera coordinate system).
 | 
					
						
							| 
									
										
										
										
											2013-01-18 02:13:36 +00:00
										 |  |  | 	VlakRen *vlr = NULL; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	unsigned numFaces = 0; | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 	float v1[3], v2[3], v3[3], v4[3]; | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 	float n1[3], n2[3], n3[3], n4[3], facenormal[3]; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	int clip_1[3], clip_2[3]; | 
					
						
							| 
									
										
										
										
											2010-06-03 15:06:23 +00:00
										 |  |  | 	int wire_material = 0; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	for (int a = 0; a < obr->totvlak; a++) { | 
					
						
							|  |  |  | 		if ((a & 255) == 0) | 
					
						
							|  |  |  | 			vlr = obr->vlaknodes[a>>8].vlak; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			vlr++; | 
					
						
							| 
									
										
										
										
											2014-06-29 21:22:24 +09:00
										 |  |  | 		if (vlr->mat->mode & MA_ONLYCAST) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2010-06-03 15:06:23 +00:00
										 |  |  | 		if (vlr->mat->material_type == MA_TYPE_WIRE) { | 
					
						
							|  |  |  | 			wire_material = 1; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 		copy_v3_v3(v1, vlr->v1->co); | 
					
						
							|  |  |  | 		copy_v3_v3(v2, vlr->v2->co); | 
					
						
							|  |  |  | 		copy_v3_v3(v3, vlr->v3->co); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		if (vlr->v4) | 
					
						
							|  |  |  | 			copy_v3_v3(v4, vlr->v4->co); | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 		if (obi->flag & R_TRANSFORMED) { | 
					
						
							|  |  |  | 			mul_m4_v3(obi->mat, v1); | 
					
						
							|  |  |  | 			mul_m4_v3(obi->mat, v2); | 
					
						
							|  |  |  | 			mul_m4_v3(obi->mat, v3); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			if (vlr->v4) | 
					
						
							|  |  |  | 				mul_m4_v3(obi->mat, v4); | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-09 23:25:02 +00:00
										 |  |  | 		v1[2] += _z_offset; | 
					
						
							|  |  |  | 		v2[2] += _z_offset; | 
					
						
							|  |  |  | 		v3[2] += _z_offset; | 
					
						
							|  |  |  | 		if (vlr->v4) | 
					
						
							|  |  |  | 			v4[2] += _z_offset; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 		print_v3("v1", v1); | 
					
						
							|  |  |  | 		print_v3("v2", v2); | 
					
						
							|  |  |  | 		print_v3("v3", v3); | 
					
						
							|  |  |  | 		if (vlr->v4) | 
					
						
							|  |  |  | 			print_v3("v4", v4); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 		if (!vlr->v4 || !testEdgeRotation(v1, v2, v3, v4)) { | 
					
						
							|  |  |  | 			numFaces += countClippedFaces(v1, v2, v3, clip_1); | 
					
						
							|  |  |  | 			if (vlr->v4) | 
					
						
							|  |  |  | 				numFaces += countClippedFaces(v1, v3, v4, clip_2); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-03-05 19:01:12 +00:00
										 |  |  | 			numFaces += countClippedFaces(v1, v2, v4, clip_1); | 
					
						
							|  |  |  | 			numFaces += countClippedFaces(v2, v3, v4, clip_2); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 	if (wire_material) { | 
					
						
							|  |  |  | 		if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 			cout << "Warning: Object " << name << " has wire materials (ignored)" << endl; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 		cout << "numFaces " << numFaces << endl; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	if (numFaces == 0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:36:12 +00:00
										 |  |  | 	// We allocate memory for the meshes to be imported
 | 
					
						
							| 
									
										
										
										
											2014-05-19 11:10:11 +09:00
										 |  |  | 	NodeGroup *currentMesh = new NodeGroup; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	NodeShape *shape = new NodeShape; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	unsigned vSize = 3 * 3 * numFaces; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	float *vertices = new float[vSize]; | 
					
						
							|  |  |  | 	unsigned nSize = vSize; | 
					
						
							|  |  |  | 	float *normals = new float[nSize]; | 
					
						
							|  |  |  | 	unsigned *numVertexPerFaces = new unsigned[numFaces]; | 
					
						
							| 
									
										
										
										
											2014-10-23 20:26:39 +09:00
										 |  |  | 	vector<Material *> meshMaterials; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	vector<FrsMaterial> meshFrsMaterials; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	IndexedFaceSet::TRIANGLES_STYLE *faceStyle = new IndexedFaceSet::TRIANGLES_STYLE[numFaces]; | 
					
						
							|  |  |  | 	unsigned i; | 
					
						
							|  |  |  | 	for (i = 0; i <numFaces; i++) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		faceStyle[i] = IndexedFaceSet::TRIANGLES; | 
					
						
							|  |  |  | 		numVertexPerFaces[i] = 3; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = new IndexedFaceSet::FaceEdgeMark[numFaces]; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	unsigned viSize = 3 * numFaces; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	unsigned *VIndices = new unsigned[viSize]; | 
					
						
							|  |  |  | 	unsigned niSize = viSize; | 
					
						
							|  |  |  | 	unsigned *NIndices = new unsigned[niSize]; | 
					
						
							|  |  |  | 	unsigned *MIndices = new unsigned[viSize]; // Material Indices
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	struct LoaderState ls; | 
					
						
							|  |  |  | 	ls.pv = vertices; | 
					
						
							|  |  |  | 	ls.pn = normals; | 
					
						
							| 
									
										
										
										
											2011-10-06 02:04:43 +00:00
										 |  |  | 	ls.pm = faceEdgeMarks; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	ls.pvi = VIndices; | 
					
						
							|  |  |  | 	ls.pni = NIndices; | 
					
						
							|  |  |  | 	ls.pmi = MIndices; | 
					
						
							|  |  |  | 	ls.currentIndex = 0; | 
					
						
							|  |  |  | 	ls.currentMIndex = 0; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	FrsMaterial tmpMat; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:36:12 +00:00
										 |  |  | 	// We parse the vlak nodes again and import meshes while applying the clipping
 | 
					
						
							|  |  |  | 	// by the near and far view planes.
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	int p; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	for (p = 0; p < obr->totvlak; ++p) { // we parse the faces of the mesh
 | 
					
						
							|  |  |  | 		if ((p & 255) == 0) | 
					
						
							|  |  |  | 			vlr = obr->vlaknodes[p>>8].vlak; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			vlr++; | 
					
						
							| 
									
										
										
										
											2014-06-29 21:22:24 +09:00
										 |  |  | 		if ((vlr->mat->mode & MA_ONLYCAST) || vlr->mat->material_type == MA_TYPE_WIRE) | 
					
						
							| 
									
										
										
										
											2013-03-16 16:41:12 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		copy_v3_v3(v1, vlr->v1->co); | 
					
						
							|  |  |  | 		copy_v3_v3(v2, vlr->v2->co); | 
					
						
							|  |  |  | 		copy_v3_v3(v3, vlr->v3->co); | 
					
						
							|  |  |  | 		if (vlr->v4) | 
					
						
							|  |  |  | 			copy_v3_v3(v4, vlr->v4->co); | 
					
						
							|  |  |  | 		if (obi->flag & R_TRANSFORMED) { | 
					
						
							|  |  |  | 			mul_m4_v3(obi->mat, v1); | 
					
						
							|  |  |  | 			mul_m4_v3(obi->mat, v2); | 
					
						
							|  |  |  | 			mul_m4_v3(obi->mat, v3); | 
					
						
							|  |  |  | 			if (vlr->v4) | 
					
						
							|  |  |  | 				mul_m4_v3(obi->mat, v4); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-09 23:25:02 +00:00
										 |  |  | 		v1[2] += _z_offset; | 
					
						
							|  |  |  | 		v2[2] += _z_offset; | 
					
						
							|  |  |  | 		v3[2] += _z_offset; | 
					
						
							|  |  |  | 		if (vlr->v4) | 
					
						
							|  |  |  | 			v4[2] += _z_offset; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		if (_smooth && (vlr->flag & R_SMOOTH)) { | 
					
						
							|  |  |  | 			copy_v3_v3(n1, vlr->v1->n); | 
					
						
							|  |  |  | 			copy_v3_v3(n2, vlr->v2->n); | 
					
						
							|  |  |  | 			copy_v3_v3(n3, vlr->v3->n); | 
					
						
							|  |  |  | 			if (vlr->v4) | 
					
						
							|  |  |  | 				copy_v3_v3(n4, vlr->v4->n); | 
					
						
							| 
									
										
										
										
											2010-02-19 01:10:04 +00:00
										 |  |  | 			if (obi->flag & R_TRANSFORMED) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 				mul_m3_v3(obi->nmat, n1); | 
					
						
							|  |  |  | 				mul_m3_v3(obi->nmat, n2); | 
					
						
							|  |  |  | 				mul_m3_v3(obi->nmat, n3); | 
					
						
							|  |  |  | 				normalize_v3(n1); | 
					
						
							|  |  |  | 				normalize_v3(n2); | 
					
						
							|  |  |  | 				normalize_v3(n3); | 
					
						
							|  |  |  | 				if (vlr->v4) { | 
					
						
							|  |  |  | 					mul_m3_v3(obi->nmat, n4); | 
					
						
							|  |  |  | 					normalize_v3(n4); | 
					
						
							| 
									
										
										
										
											2010-12-12 13:16:35 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-11-27 11:23:11 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			RE_vlakren_get_normal(_re, obi, vlr, facenormal); | 
					
						
							| 
									
										
										
										
											2014-05-17 17:40:04 +09:00
										 |  |  | #ifndef NDEBUG
 | 
					
						
							|  |  |  | 			float tnor[3]; | 
					
						
							|  |  |  | 			normal_tri_v3(tnor, v3, v2, v1);  /* normals are inverted in rendering */ | 
					
						
							|  |  |  | 			BLI_assert(dot_v3v3(tnor, facenormal) > 0.0f); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			copy_v3_v3(n1, facenormal); | 
					
						
							|  |  |  | 			copy_v3_v3(n2, facenormal); | 
					
						
							|  |  |  | 			copy_v3_v3(n3, facenormal); | 
					
						
							|  |  |  | 			if (vlr->v4) | 
					
						
							|  |  |  | 				copy_v3_v3(n4, facenormal); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		unsigned int numTris_1, numTris_2; | 
					
						
							|  |  |  | 		bool edge_rotation; | 
					
						
							|  |  |  | 		if (!vlr->v4 || !testEdgeRotation(v1, v2, v3, v4)) { | 
					
						
							|  |  |  | 			numTris_1 = countClippedFaces(v1, v2, v3, clip_1); | 
					
						
							|  |  |  | 			numTris_2 = (!vlr->v4) ? 0 : countClippedFaces(v1, v3, v4, clip_2); | 
					
						
							|  |  |  | 			edge_rotation = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			numTris_1 = countClippedFaces(v1, v2, v4, clip_1); | 
					
						
							|  |  |  | 			numTris_2 = countClippedFaces(v2, v3, v4, clip_2); | 
					
						
							|  |  |  | 			edge_rotation = true; | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 			if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 				printf("BlenderFileLoader::insertShapeNode: edge rotation is performed.\n"); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (numTris_1 == 0 && numTris_2 == 0) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		bool fm, em1, em2, em3, em4; | 
					
						
							| 
									
										
										
										
											2013-03-13 06:44:43 +00:00
										 |  |  | 		fm = (vlr->freestyle_face_mark) != 0; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		em1 = (vlr->freestyle_edge_mark & R_EDGE_V1V2) != 0; | 
					
						
							|  |  |  | 		em2 = (vlr->freestyle_edge_mark & R_EDGE_V2V3) != 0; | 
					
						
							|  |  |  | 		if (!vlr->v4) { | 
					
						
							|  |  |  | 			em3 = (vlr->freestyle_edge_mark & R_EDGE_V3V1) != 0; | 
					
						
							|  |  |  | 			em4 = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			em3 = (vlr->freestyle_edge_mark & R_EDGE_V3V4) != 0; | 
					
						
							|  |  |  | 			em4 = (vlr->freestyle_edge_mark & R_EDGE_V4V1) != 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Material *mat = vlr->mat; | 
					
						
							|  |  |  | 		if (mat) { | 
					
						
							| 
									
										
										
										
											2014-07-07 15:54:46 +09:00
										 |  |  | 			tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			tmpMat.setDiffuse(mat->r, mat->g, mat->b, mat->alpha); | 
					
						
							|  |  |  | 			tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, mat->spectra); | 
					
						
							|  |  |  | 			float s = 1.0 * (mat->har + 1) / 4 ; // in Blender: [1;511] => in OpenGL: [0;128]
 | 
					
						
							|  |  |  | 			if (s > 128.f) | 
					
						
							|  |  |  | 				s = 128.f; | 
					
						
							|  |  |  | 			tmpMat.setShininess(s); | 
					
						
							| 
									
										
										
										
											2014-07-07 15:54:46 +09:00
										 |  |  | 			tmpMat.setPriority(mat->line_priority); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-23 20:26:39 +09:00
										 |  |  | 		if (meshMaterials.empty()) { | 
					
						
							|  |  |  | 			meshMaterials.push_back(mat); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			meshFrsMaterials.push_back(tmpMat); | 
					
						
							|  |  |  | 			shape->setFrsMaterial(tmpMat); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2014-10-23 20:26:39 +09:00
										 |  |  | 			// find if the Blender material is already in the list
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			unsigned int i = 0; | 
					
						
							|  |  |  | 			bool found = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-23 20:26:39 +09:00
										 |  |  | 			for (vector<Material *>::iterator it = meshMaterials.begin(), itend = meshMaterials.end(); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			     it != itend; | 
					
						
							|  |  |  | 			     it++, i++) | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2014-10-23 20:26:39 +09:00
										 |  |  | 				if (*it == mat) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 					ls.currentMIndex = i; | 
					
						
							|  |  |  | 					found = true; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (!found) { | 
					
						
							| 
									
										
										
										
											2014-10-23 20:26:39 +09:00
										 |  |  | 				meshMaterials.push_back(mat); | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 				meshFrsMaterials.push_back(tmpMat); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 				ls.currentMIndex = meshFrsMaterials.size() - 1; | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-08-08 08:25:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		float triCoords[5][3], triNormals[5][3]; | 
					
						
							|  |  |  | 		bool edgeMarks[5]; // edgeMarks[i] is for the edge between i-th and (i+1)-th vertices
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (numTris_1 > 0) { | 
					
						
							|  |  |  | 			if (!edge_rotation) { | 
					
						
							|  |  |  | 				clipTriangle(numTris_1, triCoords, v1, v2, v3, triNormals, n1, n2, n3, | 
					
						
							|  |  |  | 				             edgeMarks, em1, em2, (!vlr->v4) ? em3 : false, clip_1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				clipTriangle(numTris_1, triCoords, v1, v2, v4, triNormals, n1, n2, n4, | 
					
						
							|  |  |  | 				             edgeMarks, em1, false, em4, clip_1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			for (i = 0; i < numTris_1; i++) { | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 				addTriangle(&ls, triCoords[0], triCoords[i + 1], triCoords[i + 2], | 
					
						
							|  |  |  | 				            triNormals[0], triNormals[i + 1], triNormals[i + 2], | 
					
						
							|  |  |  | 				            fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1], | 
					
						
							|  |  |  | 				            (i == numTris_1 - 1) ? edgeMarks[i + 2] : false); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 				_numFacesRead++; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (numTris_2 > 0) { | 
					
						
							|  |  |  | 			if (!edge_rotation) { | 
					
						
							|  |  |  | 				clipTriangle(numTris_2, triCoords, v1, v3, v4, triNormals, n1, n3, n4, | 
					
						
							|  |  |  | 				             edgeMarks, false, em3, em4, clip_2); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				clipTriangle(numTris_2, triCoords, v2, v3, v4, triNormals, n2, n3, n4, | 
					
						
							|  |  |  | 				             edgeMarks, em2, em3, false, clip_2); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			for (i = 0; i < numTris_2; i++) { | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 				addTriangle(&ls, triCoords[0], triCoords[i + 1], triCoords[i + 2], | 
					
						
							|  |  |  | 				            triNormals[0], triNormals[i + 1], triNormals[i + 2], | 
					
						
							|  |  |  | 				            fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1], | 
					
						
							|  |  |  | 				            (i == numTris_2 - 1) ? edgeMarks[i + 2] : false); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 				_numFacesRead++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	// We might have several times the same vertex. We want a clean 
 | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	// shape with no real-vertex. Here, we are making a cleaning pass.
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	real *cleanVertices = NULL; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	unsigned int cvSize; | 
					
						
							|  |  |  | 	unsigned int *cleanVIndices = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GeomCleaner::CleanIndexedVertexArray(vertices, vSize, VIndices, viSize, &cleanVertices, &cvSize, &cleanVIndices); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	real *cleanNormals = NULL; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	unsigned int cnSize; | 
					
						
							|  |  |  | 	unsigned int *cleanNIndices = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GeomCleaner::CleanIndexedVertexArray(normals, nSize, NIndices, niSize, &cleanNormals, &cnSize, &cleanNIndices); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	// format materials array
 | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 	FrsMaterial **marray = new FrsMaterial *[meshFrsMaterials.size()]; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	unsigned int mindex = 0; | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 	for (vector<FrsMaterial>::iterator m = meshFrsMaterials.begin(), mend = meshFrsMaterials.end(); m != mend; ++m) { | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		marray[mindex] = new FrsMaterial(*m); | 
					
						
							|  |  |  | 		++mindex; | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	// deallocates memory:
 | 
					
						
							|  |  |  | 	delete [] vertices; | 
					
						
							|  |  |  | 	delete [] normals; | 
					
						
							|  |  |  | 	delete [] VIndices; | 
					
						
							|  |  |  | 	delete [] NIndices; | 
					
						
							| 
									
										
										
										
											2012-02-29 01:11:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 	// Fix for degenerated triangles
 | 
					
						
							| 
									
										
										
										
											2012-02-29 01:11:37 +00:00
										 |  |  | 	// A degenerate triangle is a triangle such that
 | 
					
						
							|  |  |  | 	// 1) A and B are in the same position in the 3D space; or
 | 
					
						
							|  |  |  | 	// 2) the distance between point P and line segment AB is zero.
 | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 	// Only those degenerate triangles in the second form are resolved here
 | 
					
						
							|  |  |  | 	// by adding a small offset to P, whereas those in the first form are
 | 
					
						
							|  |  |  | 	// addressed later in WShape::MakeFace().
 | 
					
						
							|  |  |  | 	vector<detri_t> detriList; | 
					
						
							|  |  |  | 	Vec3r zero(0.0, 0.0, 0.0); | 
					
						
							|  |  |  | 	unsigned vi0, vi1, vi2; | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 	for (i = 0; i < viSize; i += 3) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 		detri_t detri; | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 		vi0 = cleanVIndices[i]; | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 		vi1 = cleanVIndices[i + 1]; | 
					
						
							|  |  |  | 		vi2 = cleanVIndices[i + 2]; | 
					
						
							|  |  |  | 		Vec3r v0(cleanVertices[vi0], cleanVertices[vi0 + 1], cleanVertices[vi0 + 2]); | 
					
						
							|  |  |  | 		Vec3r v1(cleanVertices[vi1], cleanVertices[vi1 + 1], cleanVertices[vi1 + 2]); | 
					
						
							|  |  |  | 		Vec3r v2(cleanVertices[vi2], cleanVertices[vi2 + 1], cleanVertices[vi2 + 2]); | 
					
						
							| 
									
										
										
										
											2012-02-29 01:11:37 +00:00
										 |  |  | 		if (v0 == v1 || v0 == v2 || v1 == v2) { | 
					
						
							| 
									
										
										
										
											2012-05-01 18:46:15 +00:00
										 |  |  | 			continue; // do nothing for now
 | 
					
						
							| 
									
										
										
										
											2012-02-29 01:11:37 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		else if (GeomUtils::distPointSegment<Vec3r>(v0, v1, v2) < 1.0e-6) { | 
					
						
							|  |  |  | 			detri.viP = vi0; | 
					
						
							|  |  |  | 			detri.viA = vi1; | 
					
						
							|  |  |  | 			detri.viB = vi2; | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		else if (GeomUtils::distPointSegment<Vec3r>(v1, v0, v2) < 1.0e-6) { | 
					
						
							|  |  |  | 			detri.viP = vi1; | 
					
						
							|  |  |  | 			detri.viA = vi0; | 
					
						
							|  |  |  | 			detri.viB = vi2; | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		else if (GeomUtils::distPointSegment<Vec3r>(v2, v0, v1) < 1.0e-6) { | 
					
						
							|  |  |  | 			detri.viP = vi2; | 
					
						
							|  |  |  | 			detri.viA = vi0; | 
					
						
							|  |  |  | 			detri.viB = vi1; | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 		detri.v = zero; | 
					
						
							|  |  |  | 		detri.n = 0; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 		for (unsigned int j = 0; j < viSize; j += 3) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 			if (i == j) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			vi0 = cleanVIndices[j]; | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 			vi1 = cleanVIndices[j + 1]; | 
					
						
							|  |  |  | 			vi2 = cleanVIndices[j + 2]; | 
					
						
							|  |  |  | 			Vec3r v0(cleanVertices[vi0], cleanVertices[vi0 + 1], cleanVertices[vi0 + 2]); | 
					
						
							|  |  |  | 			Vec3r v1(cleanVertices[vi1], cleanVertices[vi1 + 1], cleanVertices[vi1 + 2]); | 
					
						
							|  |  |  | 			Vec3r v2(cleanVertices[vi2], cleanVertices[vi2 + 1], cleanVertices[vi2 + 2]); | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 			if (detri.viP == vi0 && (detri.viA == vi1 || detri.viB == vi1)) { | 
					
						
							|  |  |  | 				detri.v += (v2 - v0); | 
					
						
							|  |  |  | 				detri.n++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (detri.viP == vi0 && (detri.viA == vi2 || detri.viB == vi2)) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 				detri.v += (v1 - v0); | 
					
						
							|  |  |  | 				detri.n++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (detri.viP == vi1 && (detri.viA == vi0 || detri.viB == vi0)) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 				detri.v += (v2 - v1); | 
					
						
							|  |  |  | 				detri.n++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (detri.viP == vi1 && (detri.viA == vi2 || detri.viB == vi2)) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 				detri.v += (v0 - v1); | 
					
						
							|  |  |  | 				detri.n++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (detri.viP == vi2 && (detri.viA == vi0 || detri.viB == vi0)) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 				detri.v += (v1 - v2); | 
					
						
							|  |  |  | 				detri.n++; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (detri.viP == vi2 && (detri.viA == vi1 || detri.viB == vi1)) { | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 				detri.v += (v0 - v2); | 
					
						
							|  |  |  | 				detri.n++; | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 		if (detri.n > 0) { | 
					
						
							|  |  |  | 			detri.v.normalizeSafe(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		detriList.push_back(detri); | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 	if (detriList.size() > 0) { | 
					
						
							|  |  |  | 		vector<detri_t>::iterator v; | 
					
						
							|  |  |  | 		for (v = detriList.begin(); v != detriList.end(); v++) { | 
					
						
							|  |  |  | 			detri_t detri = (*v); | 
					
						
							|  |  |  | 			if (detri.n == 0) { | 
					
						
							|  |  |  | 				cleanVertices[detri.viP]   = cleanVertices[detri.viA]; | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 				cleanVertices[detri.viP + 1] = cleanVertices[detri.viA + 1]; | 
					
						
							|  |  |  | 				cleanVertices[detri.viP + 2] = cleanVertices[detri.viA + 2]; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (detri.v.norm() > 0.0) { | 
					
						
							|  |  |  | 				cleanVertices[detri.viP]   += 1.0e-5 * detri.v.x(); | 
					
						
							| 
									
										
										
										
											2013-03-07 23:17:23 +00:00
										 |  |  | 				cleanVertices[detri.viP + 1] += 1.0e-5 * detri.v.y(); | 
					
						
							|  |  |  | 				cleanVertices[detri.viP + 2] += 1.0e-5 * detri.v.z(); | 
					
						
							| 
									
										
										
										
											2012-03-03 01:03:20 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		if (G.debug & G_DEBUG_FREESTYLE) { | 
					
						
							|  |  |  | 			printf("Warning: Object %s contains %lu degenerated triangle%s (strokes may be incorrect)\n", | 
					
						
							| 
									
										
										
										
											2014-04-18 09:25:36 +09:00
										 |  |  | 			       name, (long unsigned int)detriList.size(), (detriList.size() > 1) ? "s" : ""); | 
					
						
							| 
									
										
										
										
											2013-01-03 23:27:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-28 20:56:31 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	// Create the IndexedFaceSet with the retrieved attributes
 | 
					
						
							| 
									
										
										
										
											2010-01-30 01:36:12 +00:00
										 |  |  | 	IndexedFaceSet *rep; | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	rep = new IndexedFaceSet(cleanVertices, cvSize, cleanNormals, cnSize, marray, meshFrsMaterials.size(), 0, 0, | 
					
						
							|  |  |  | 	                         numFaces, numVertexPerFaces, faceStyle, faceEdgeMarks, cleanVIndices, viSize, | 
					
						
							|  |  |  | 	                         cleanNIndices, niSize, MIndices, viSize, 0, 0, 0); | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	// sets the id of the rep
 | 
					
						
							|  |  |  | 	rep->setId(Id(id, 0)); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 	rep->setName(obi->ob->id.name + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]), | 
					
						
							| 
									
										
										
										
											2010-01-24 23:12:57 +00:00
										 |  |  | 	                                     Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2])); | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	rep->setBBox(bbox); | 
					
						
							|  |  |  | 	shape->AddRep(rep); | 
					
						
							| 
									
										
										
										
											2012-12-18 00:51:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 15:04:25 +00:00
										 |  |  | 	currentMesh->AddChild(shape); | 
					
						
							|  |  |  | 	_Scene->AddChild(currentMesh); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-04-09 00:46:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | } /* namespace Freestyle */ |