/// <summary> /// Calculates the facets of a surface, storing them in a <see cref="MeshController"/>. /// </summary> private void CalculateSurfaceFacets(SurfaceBody surf, MeshController outputMesh, bool separateFaces = false, BackgroundWorker backgroundWorker = null) { if (backgroundWorker != null && backgroundWorker.CancellationPending) { return; } double tolerance = DEFAULT_TOLERANCE; PartialSurface bufferSurface = new PartialSurface(); // Store a list of faces separate from the Inventor API Faces faces = surf.Faces; // Don't separate if only one color if (separateFaces) { separateFaces = MultipleAssets(faces); } // Do separate if too many faces if (!separateFaces) { surf.CalculateFacets(tolerance, out bufferSurface.verts.count, out bufferSurface.facets.count, out bufferSurface.verts.coordinates, out bufferSurface.verts.norms, out bufferSurface.facets.indices); if (bufferSurface.verts.count > MAX_VERTS_OR_FACETS || bufferSurface.facets.count > MAX_VERTS_OR_FACETS) { separateFaces = true; } } if (separateFaces) { // Add facets for each face of the surface foreach (Face face in faces) { if (face.Appearance != null) { face.CalculateFacets(tolerance, out bufferSurface.verts.count, out bufferSurface.facets.count, out bufferSurface.verts.coordinates, out bufferSurface.verts.norms, out bufferSurface.facets.indices); outputMesh.AddSurface(ref bufferSurface, GetAssetProperties(face.Appearance)); } } } else { // Add facets once for the entire surface AssetProperties asset; try { asset = GetAssetProperties(faces[1].Appearance); } catch (Exception) { asset = new AssetProperties(); } outputMesh.AddSurface(ref bufferSurface, asset); } }
/// <summary> /// Adds a surface to the output mesh. Not saved as a sub-surface until <see cref="DumpOutput"/> is called. /// </summary> /// <param name="bufferSurface">Surface to add to mesh.</param> /// <param name="asset">Asset for surface.</param> public void AddSurface(ref PartialSurface bufferSurface, AssetProperties asset) { // Create new surface BXDAMesh.BXDASurface newMeshSurface = new BXDAMesh.BXDASurface(); // Apply Asset Properties if (asset == null) { return; } newMeshSurface.hasColor = true; newMeshSurface.color = asset.color; newMeshSurface.transparency = (float)asset.transparency; newMeshSurface.translucency = (float)asset.translucency; newMeshSurface.specular = (float)asset.specular; // Prevent too many vertices if (bufferSurface.verts.count > MAX_VERTS_OR_FACETS) { throw new TooManyVerticesException(); } int indexOffset; lock (outputVerts) { // Prevent too many vertices if (outputVerts.count + bufferSurface.verts.count > MAX_VERTS_OR_FACETS) { DumpOutputInternal(); } // Copy buffer vertices into output Array.Copy(bufferSurface.verts.coordinates, 0, outputVerts.coordinates, outputVerts.count * 3, bufferSurface.verts.count * 3); Array.Copy(bufferSurface.verts.norms, 0, outputVerts.norms, outputVerts.count * 3, bufferSurface.verts.count * 3); // Store length of output verts for later indexOffset = outputVerts.count - 1; outputVerts.count += bufferSurface.verts.count; } // Copy buffer surface into output, incrementing indices relative to where verts where stitched into the vert array newMeshSurface.indicies = new int[bufferSurface.facets.count * 3]; for (int i = 0; i < bufferSurface.facets.count * 3; i++) { newMeshSurface.indicies[i] = bufferSurface.facets.indices[i] + indexOffset; // Why does Inventor start from 1?! } // Add the new surface to the output lock (outputMeshSurfaces) outputMeshSurfaces.Add(newMeshSurface); // Empty buffer bufferSurface.verts.count = 0; bufferSurface.facets.count = 0; }