<commit_before><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
	 "http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>

	<meta http-equiv="content-type" content="text/html;charset=utf-8">
	<script type="text/javascript" src="../build/three.min.js"></script>
<!-- JSModeler includes start -->
	<script type="text/javascript" src="../src/core/jsm.js"></script>
	<script type="text/javascript" src="../src/core/timer.js"></script>
	<script type="text/javascript" src="../src/core/algorithm.js"></script>
	<script type="text/javascript" src="../src/core/async.js"></script>
	<script type="text/javascript" src="../src/core/check.js"></script>
	<script type="text/javascript" src="../src/geometry/definitions.js"></script>
	<script type="text/javascript" src="../src/geometry/coord2d.js"></script>
	<script type="text/javascript" src="../src/geometry/coord.js"></script>
	<script type="text/javascript" src="../src/geometry/determinant.js"></script>
	<script type="text/javascript" src="../src/geometry/coordutils.js"></script>
	<script type="text/javascript" src="../src/geometry/matrix.js"></script>
	<script type="text/javascript" src="../src/geometry/coordsystem.js"></script>
	<script type="text/javascript" src="../src/geometry/sector.js"></script>
	<script type="text/javascript" src="../src/geometry/line.js"></script>
	<script type="text/javascript" src="../src/geometry/box.js"></script>
	<script type="text/javascript" src="../src/geometry/sphere.js"></script>
	<script type="text/javascript" src="../src/geometry/transformation.js"></script>
	<script type="text/javascript" src="../src/geometry/plane.js"></script>
	<script type="text/javascript" src="../src/geometry/projection.js"></script>
	<script type="text/javascript" src="../src/geometry/convexhull.js"></script>
	<script type="text/javascript" src="../src/geometry/polygon2d.js"></script>
	<script type="text/javascript" src="../src/geometry/polygon.js"></script>
	<script type="text/javascript" src="../src/geometry/triangulation.js"></script>
	<script type="text/javascript" src="../src/geometry/octree.js"></script>
	<script type="text/javascript" src="../src/geometry/bsptree.js"></script>
	<script type="text/javascript" src="../src/geometry/utilities.js"></script>
	<script type="text/javascript" src="../src/geometry/ray.js"></script>
	<script type="text/javascript" src="../src/modeler/body.js"></script>
	<script type="text/javascript" src="../src/modeler/model.js"></script>
	<script type="text/javascript" src="../src/modeler/color.js"></script>
	<script type="text/javascript" src="../src/modeler/light.js"></script>
	<script type="text/javascript" src="../src/modeler/material.js"></script>
	<script type="text/javascript" src="../src/modeler/adjacencyinfo.js"></script>
	<script type="text/javascript" src="../src/modeler/bodyutils.js"></script>
	<script type="text/javascript" src="../src/modeler/textureutils.js"></script>
	<script type="text/javascript" src="../src/modeler/cututils.js"></script>
	<script type="text/javascript" src="../src/modeler/generator.js"></script>
	<script type="text/javascript" src="../src/modeler/camera.js"></script>
	<script type="text/javascript" src="../src/modeler/explode.js"></script>
	<script type="text/javascript" src="../src/modeler/exporter.js"></script>
	<script type="text/javascript" src="../src/modeler/trianglebody.js"></script>
	<script type="text/javascript" src="../src/modeler/trianglemodel.js"></script>
	<script type="text/javascript" src="../src/modeler/converter.js"></script>
	<script type="text/javascript" src="../src/modeler/rayutils.js"></script>
	<script type="text/javascript" src="../src/import/binaryreader.js"></script>
	<script type="text/javascript" src="../src/import/importer.js"></script>
	<script type="text/javascript" src="../src/import/importer3ds.js"></script>
	<script type="text/javascript" src="../src/import/importerobj.js"></script>
	<script type="text/javascript" src="../src/import/importerstl.js"></script>
	<script type="text/javascript" src="../src/import/importercommon.js"></script>
	<script type="text/javascript" src="../src/renderer/webglutils.js"></script>
	<script type="text/javascript" src="../src/renderer/renderdata.js"></script>
	<script type="text/javascript" src="../src/renderer/shaderprogram.js"></script>
	<script type="text/javascript" src="../src/renderer/renderer.js"></script>
	<script type="text/javascript" src="../src/renderer/pointcloudrenderer.js"></script>
	<script type="text/javascript" src="../src/renderer/renderconverter.js"></script>
	<script type="text/javascript" src="../src/viewer/jsonfileloader.js"></script>
	<script type="text/javascript" src="../src/viewer/mouse.js"></script>
	<script type="text/javascript" src="../src/viewer/touch.js"></script>
	<script type="text/javascript" src="../src/viewer/painter.js"></script>
	<script type="text/javascript" src="../src/viewer/drawing.js"></script>
	<script type="text/javascript" src="../src/viewer/navigation.js"></script>
	<script type="text/javascript" src="../src/viewer/softwareviewer.js"></script>
	<script type="text/javascript" src="../src/viewer/spriteviewer.js"></script>
	<script type="text/javascript" src="../src/viewer/viewer.js"></script>
	<script type="text/javascript" src="../src/viewer/pointcloudviewer.js"></script>
	<script type="text/javascript" src="../src/extras/solidgenerator.js"></script>
	<script type="text/javascript" src="../src/extras/extgenerator.js"></script>
	<script type="text/javascript" src="../src/extras/subdivision.js"></script>
	<script type="text/javascript" src="../src/extras/svgtomodel.js"></script>
	<script type="text/javascript" src="../src/extras/csg.js"></script>
	<script type="text/javascript" src="../src/extras/curves.js"></script>
	<script type="text/javascript" src="../src/three/threeconverter.js"></script>
	<script type="text/javascript" src="../src/three/threeviewer.js"></script>
<!-- JSModeler includes end -->
	<title>Example</title>

	<script type="text/javascript">
		JSM.PushPullBodyPolygon = function (body, polygonIndex, distance)
		{
			function OffsetPolygonVertex (body, polygon, normal, vertexIndex)
			{
				var oldBodyVertexIndex = polygon.GetVertexIndex (vertexIndex);
				var offsetedCoord = body.GetVertexPosition (oldBodyVertexIndex).Clone ().Offset (normal, distance);
				var newBodyVertexIndex = body.AddVertex (new JSM.BodyVertex (offsetedCoord));
				polygon.SetVertexIndex (vertexIndex, newBodyVertexIndex);
			}
		
			function CreateSidePolygon (body, oldPolygon, polygon, vertexIndex)
			{
				var oldBodyVertexIndex = oldPolygon.GetVertexIndex (vertexIndex);
				var newBodyVertexIndex = polygon.GetVertexIndex (vertexIndex);
				var nextIndex = JSM.NextIndex (vertexIndex, oldPolygon.VertexIndexCount ());
				var oldNextBodyVertexIndex = oldPolygon.GetVertexIndex (nextIndex);
				var newNextBodyVertexIndex = polygon.GetVertexIndex (nextIndex);
				var sidePolygonVertices = [oldBodyVertexIndex, oldNextBodyVertexIndex, newNextBodyVertexIndex, newBodyVertexIndex];
				var sidePolygon = new JSM.BodyPolygon (sidePolygonVertices);
				sidePolygon.SetMaterialIndex (oldPolygon.GetMaterialIndex ());
				body.AddPolygon (sidePolygon);
			}

			function IsVertexMovingSituation (body, polygonIndex, polygonNormal)
			{
				function CanMovePolygonVertex (body, polygonIndex, polygonNormal, vertexNeighbourPolygons, polygonNormals)
				{
					if (vertexNeighbourPolygons.length === 1) {
						return false;
					}
					var i, neighbourPolygon, neighbourPolygonNormal;
					for (i = 0; i < vertexNeighbourPolygons.length; i++) {
						neighbourPolygon = vertexNeighbourPolygons[i];
						if (neighbourPolygon == polygonIndex) {
							continue;
						}
						neighbourPolygonNormal = polygonNormals[neighbourPolygon];
						if (neighbourPolygonNormal === undefined) {
							neighbourPolygonNormal = JSM.CalculateBodyPolygonNormal (body, neighbourPolygon);
							polygonNormals[neighbourPolygon] = neighbourPolygonNormal;
						}
						if (!polygonNormal.IsPerpendicularWith (neighbourPolygonNormal)) {
							return false;
						}
					}
					return true;
				}
			
				var polygon = body.GetPolygon (polygonIndex);
				var vertexToPolygon = JSM.CalculateBodyVertexToPolygon (body);
				var polygonNormals = {};
				var i, neighbourPolygons;
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					neighbourPolygons = vertexToPolygon[polygon.GetVertexIndex (i)];
					if (!CanMovePolygonVertex (body, polygonIndex, polygonNormal, neighbourPolygons, polygonNormals)) {
						return false;
					}
				}
				return true;
			}
			
			function OffsetPolygonWithVertexMoving (body, polygon, normal)
			{
				var i, vertex;
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					vertex = body.GetVertexPosition (polygon.GetVertexIndex (i));
					vertex.Offset (normal, distance);
				}			
			}
			
			function OffsetPolygonWithVertexDuplication (body, polygon, normal)
			{
				var oldPolygon = polygon.Clone ();
				var i;
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					OffsetPolygonVertex (body, polygon, normal, i);
				}
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					CreateSidePolygon (body, oldPolygon, polygon, i);
				}		
			}

			var polygon = body.GetPolygon (polygonIndex);
			var normal = JSM.CalculateBodyPolygonNormal (body, polygonIndex);

			if (IsVertexMovingSituation (body, polygonIndex, normal)) {
				OffsetPolygonWithVertexMoving (body, polygon, normal);
			} else {
				OffsetPolygonWithVertexDuplication (body, polygon, normal);
			}
		};
	
		function Load ()
		{
			var camera = new JSM.Camera (
				new JSM.Coord (-1.0, -3.0, 2.0),
				new JSM.Coord (0.0, 0.0, 0.0),
				new JSM.Vector (0.0, 0.0, 1.0)
			);
			
			var light = new JSM.Light ();
			
			var viewer = new JSM.Viewer ();
			if (!viewer.Init (document.getElementById ('example'), camera, light)) {
				alert ('error');
			}

			var materials = new JSM.Materials ();
			materials.AddMaterial (new JSM.Material ({ambient : 0xcc0000, diffuse : 0xcc0000}));
			materials.AddMaterial (new JSM.Material ({ambient : 0x0000cc, diffuse : 0x0000cc}));

			var body = new JSM.Body ();
			JSM.AddVertexToBody (body, 0, 0, 0);
			JSM.AddVertexToBody (body, 1, 0, 0);
			JSM.AddVertexToBody (body, 2, 0, 0);
			JSM.AddVertexToBody (body, 2, 1, 0);<commit_msg>Duplicate polygon in case of push-pulling a single polygon with no neighbours.<commit_after><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
	 "http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>

	<meta http-equiv="content-type" content="text/html;charset=utf-8">
	<script type="text/javascript" src="../build/three.min.js"></script>
<!-- JSModeler includes start -->
	<script type="text/javascript" src="../src/core/jsm.js"></script>
	<script type="text/javascript" src="../src/core/timer.js"></script>
	<script type="text/javascript" src="../src/core/algorithm.js"></script>
	<script type="text/javascript" src="../src/core/async.js"></script>
	<script type="text/javascript" src="../src/core/check.js"></script>
	<script type="text/javascript" src="../src/geometry/definitions.js"></script>
	<script type="text/javascript" src="../src/geometry/coord2d.js"></script>
	<script type="text/javascript" src="../src/geometry/coord.js"></script>
	<script type="text/javascript" src="../src/geometry/determinant.js"></script>
	<script type="text/javascript" src="../src/geometry/coordutils.js"></script>
	<script type="text/javascript" src="../src/geometry/matrix.js"></script>
	<script type="text/javascript" src="../src/geometry/coordsystem.js"></script>
	<script type="text/javascript" src="../src/geometry/sector.js"></script>
	<script type="text/javascript" src="../src/geometry/line.js"></script>
	<script type="text/javascript" src="../src/geometry/box.js"></script>
	<script type="text/javascript" src="../src/geometry/sphere.js"></script>
	<script type="text/javascript" src="../src/geometry/transformation.js"></script>
	<script type="text/javascript" src="../src/geometry/plane.js"></script>
	<script type="text/javascript" src="../src/geometry/projection.js"></script>
	<script type="text/javascript" src="../src/geometry/convexhull.js"></script>
	<script type="text/javascript" src="../src/geometry/polygon2d.js"></script>
	<script type="text/javascript" src="../src/geometry/polygon.js"></script>
	<script type="text/javascript" src="../src/geometry/triangulation.js"></script>
	<script type="text/javascript" src="../src/geometry/octree.js"></script>
	<script type="text/javascript" src="../src/geometry/bsptree.js"></script>
	<script type="text/javascript" src="../src/geometry/utilities.js"></script>
	<script type="text/javascript" src="../src/geometry/ray.js"></script>
	<script type="text/javascript" src="../src/modeler/body.js"></script>
	<script type="text/javascript" src="../src/modeler/model.js"></script>
	<script type="text/javascript" src="../src/modeler/color.js"></script>
	<script type="text/javascript" src="../src/modeler/light.js"></script>
	<script type="text/javascript" src="../src/modeler/material.js"></script>
	<script type="text/javascript" src="../src/modeler/adjacencyinfo.js"></script>
	<script type="text/javascript" src="../src/modeler/bodyutils.js"></script>
	<script type="text/javascript" src="../src/modeler/textureutils.js"></script>
	<script type="text/javascript" src="../src/modeler/cututils.js"></script>
	<script type="text/javascript" src="../src/modeler/generator.js"></script>
	<script type="text/javascript" src="../src/modeler/camera.js"></script>
	<script type="text/javascript" src="../src/modeler/explode.js"></script>
	<script type="text/javascript" src="../src/modeler/exporter.js"></script>
	<script type="text/javascript" src="../src/modeler/trianglebody.js"></script>
	<script type="text/javascript" src="../src/modeler/trianglemodel.js"></script>
	<script type="text/javascript" src="../src/modeler/converter.js"></script>
	<script type="text/javascript" src="../src/modeler/rayutils.js"></script>
	<script type="text/javascript" src="../src/import/binaryreader.js"></script>
	<script type="text/javascript" src="../src/import/importer.js"></script>
	<script type="text/javascript" src="../src/import/importer3ds.js"></script>
	<script type="text/javascript" src="../src/import/importerobj.js"></script>
	<script type="text/javascript" src="../src/import/importerstl.js"></script>
	<script type="text/javascript" src="../src/import/importercommon.js"></script>
	<script type="text/javascript" src="../src/renderer/webglutils.js"></script>
	<script type="text/javascript" src="../src/renderer/renderdata.js"></script>
	<script type="text/javascript" src="../src/renderer/shaderprogram.js"></script>
	<script type="text/javascript" src="../src/renderer/renderer.js"></script>
	<script type="text/javascript" src="../src/renderer/pointcloudrenderer.js"></script>
	<script type="text/javascript" src="../src/renderer/renderconverter.js"></script>
	<script type="text/javascript" src="../src/viewer/jsonfileloader.js"></script>
	<script type="text/javascript" src="../src/viewer/mouse.js"></script>
	<script type="text/javascript" src="../src/viewer/touch.js"></script>
	<script type="text/javascript" src="../src/viewer/painter.js"></script>
	<script type="text/javascript" src="../src/viewer/drawing.js"></script>
	<script type="text/javascript" src="../src/viewer/navigation.js"></script>
	<script type="text/javascript" src="../src/viewer/softwareviewer.js"></script>
	<script type="text/javascript" src="../src/viewer/spriteviewer.js"></script>
	<script type="text/javascript" src="../src/viewer/viewer.js"></script>
	<script type="text/javascript" src="../src/viewer/pointcloudviewer.js"></script>
	<script type="text/javascript" src="../src/extras/solidgenerator.js"></script>
	<script type="text/javascript" src="../src/extras/extgenerator.js"></script>
	<script type="text/javascript" src="../src/extras/subdivision.js"></script>
	<script type="text/javascript" src="../src/extras/svgtomodel.js"></script>
	<script type="text/javascript" src="../src/extras/csg.js"></script>
	<script type="text/javascript" src="../src/extras/curves.js"></script>
	<script type="text/javascript" src="../src/three/threeconverter.js"></script>
	<script type="text/javascript" src="../src/three/threeviewer.js"></script>
<!-- JSModeler includes end -->
	<title>Example</title>

	<script type="text/javascript">
		JSM.PushPullBodyPolygon = function (body, polygonIndex, distance)
		{
			function DetectSituation (body, polygonIndex, polygonNormal)
			{
				function CanMovePolygonVertex (body, polygonIndex, polygonNormal, vertexNeighbourPolygons, polygonNormals)
				{
					if (vertexNeighbourPolygons.length === 1) {
						return false;
					}
					var i, neighbourPolygon, neighbourPolygonNormal;
					for (i = 0; i < vertexNeighbourPolygons.length; i++) {
						neighbourPolygon = vertexNeighbourPolygons[i];
						if (neighbourPolygon == polygonIndex) {
							continue;
						}
						neighbourPolygonNormal = polygonNormals[neighbourPolygon];
						if (neighbourPolygonNormal === undefined) {
							neighbourPolygonNormal = JSM.CalculateBodyPolygonNormal (body, neighbourPolygon);
							polygonNormals[neighbourPolygon] = neighbourPolygonNormal;
						}
						if (!polygonNormal.IsPerpendicularWith (neighbourPolygonNormal)) {
							return false;
						}
					}
					return true;
				}
			
				var polygon = body.GetPolygon (polygonIndex);
				var vertexToPolygon = JSM.CalculateBodyVertexToPolygon (body);
				var hasNeighbour = false;
				var polygonNormals = {};
				var i, vertexNeighbourPolygons;
				var situation = 0;
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					vertexNeighbourPolygons = vertexToPolygon[polygon.GetVertexIndex (i)];
					if (!hasNeighbour && vertexNeighbourPolygons.length > 1) {
						hasNeighbour = true;
					}
					if (!CanMovePolygonVertex (body, polygonIndex, polygonNormal, vertexNeighbourPolygons, polygonNormals)) {
						situation = 1;
					}
				}
				if (situation == 1 && !hasNeighbour) {
					situation = 2;
				}
				return situation;
			}
			
			function OffsetPolygonWithVertexMoving (body, polygon, normal)
			{
				var i, vertex;
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					vertex = body.GetVertexPosition (polygon.GetVertexIndex (i));
					vertex.Offset (normal, distance);
				}			
			}
			
			function OffsetPolygonWithVertexDuplication (body, polygon, normal, duplicatePolygon)
			{
				function OffsetPolygonVertex (body, polygon, normal, vertexIndex)
				{
					var oldBodyVertexIndex = polygon.GetVertexIndex (vertexIndex);
					var offsetedCoord = body.GetVertexPosition (oldBodyVertexIndex).Clone ().Offset (normal, distance);
					var newBodyVertexIndex = body.AddVertex (new JSM.BodyVertex (offsetedCoord));
					polygon.SetVertexIndex (vertexIndex, newBodyVertexIndex);
				}
			
				function CreateSidePolygon (body, oldPolygon, polygon, vertexIndex)
				{
					var oldBodyVertexIndex = oldPolygon.GetVertexIndex (vertexIndex);
					var newBodyVertexIndex = polygon.GetVertexIndex (vertexIndex);
					var nextIndex = JSM.NextIndex (vertexIndex, oldPolygon.VertexIndexCount ());
					var oldNextBodyVertexIndex = oldPolygon.GetVertexIndex (nextIndex);
					var newNextBodyVertexIndex = polygon.GetVertexIndex (nextIndex);
					var sidePolygonVertices = [oldBodyVertexIndex, oldNextBodyVertexIndex, newNextBodyVertexIndex, newBodyVertexIndex];
					var sidePolygon = new JSM.BodyPolygon (sidePolygonVertices);
					sidePolygon.SetMaterialIndex (oldPolygon.GetMaterialIndex ());
					body.AddPolygon (sidePolygon);
				}

				var oldPolygon = polygon.Clone ();
				var i;
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					OffsetPolygonVertex (body, polygon, normal, i);
				}
				for (i = 0; i < polygon.VertexIndexCount (); i++) {
					CreateSidePolygon (body, oldPolygon, polygon, i);
				}
				if (duplicatePolygon) {
					oldPolygon.ReverseVertexIndices ();
					body.AddPolygon (oldPolygon);
				}
			}

			var polygon = body.GetPolygon (polygonIndex);
			var normal = JSM.CalculateBodyPolygonNormal (body, polygonIndex);

			var situation = DetectSituation (body, polygonIndex, normal);
			if (situation === 0) {
				OffsetPolygonWithVertexMoving (body, polygon, normal);
			} else if (situation === 1 || situation == 2) {
				var duplicatePolygon = (situation == 2);
				OffsetPolygonWithVertexDuplication (body, polygon, normal, duplicatePolygon);
			}
		};
	
		function Load ()
		{
			var camera = new JSM.Camera (
				new JSM.Coord (-1.0, -3.0, 2.0),
				new JSM.Coord (0.0, 0.0, 0.0),
				new JSM.Vector (0.0, 0.0, 1.0)
			);
			
			var light = new JSM.Light ();
			
			var viewer = new JSM.Viewer ();
			if (!viewer.Init (document.getElementById ('example'), camera, light)) {
				alert ('error');
			}

			var materials = new JSM.Materials ();
			materials.AddMaterial (new JSM.Material ({ambient : 0xcc0000, diffuse : 0xcc0000}));
			materials.AddMaterial (new JSM.Material ({ambient : 0x0000cc, diffuse : 0x0000cc}));

			var body = new JSM.Body ();
			JSM.AddVertexToBody (body, 0, 0, 0);
			JSM.AddVertexToBody (body, 1, 0, 0);
			JSM.AddVertexToBody (body, 2, 0, 0);
			JSM.AddVertexToBody (body, 2, 1, 0);
{'fraction_non_alphanumeric': 0.18186535830542058, 'fraction_numerical': 0.0066518847006651885, 'mean_word_length': 4.377473363774734, 'pattern_counts': {'":': 0, '<': 331, '<?xml version=': 0, '>': 322, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2059408', 'n_tokens_mistral': 7597, 'n_tokens_neox': 6623, 'n_words': 1164}