Exemplo n.º 1
0
        /// <summary>
        /// Create the Polygonal Faces for a new Tessellated Solid by extruding the given loop along the given normal.
        /// </summary>
        /// <param name="loops"></param>
        /// <param name="extrudeDirection"></param>
        /// <param name="extrusionHeight"></param>
        /// <param name="midPlane"></param>
        /// <returns></returns>
        public static List <PolygonalFace> ExtrusionFacesFrom3DLoops(this IEnumerable <IEnumerable <Vector3> > loops, Vector3 extrudeDirection,
                                                                     double extrusionHeight, bool midPlane = false)
        {
            // for consistency with adding the extrusionHeight to the base plane, negate if it comes in negative
            if (extrusionHeight < 0)
            {
                extrusionHeight  = -extrusionHeight;
                extrudeDirection = -1 * extrudeDirection;
            }
            // find transform to the XY plane and store the backTransform (the transform back to the original)
            var transform = MiscFunctions.TransformToXYPlane(extrudeDirection, out var backTransform);
            // make paths, the 2D polygons represening the 3D loops
            var paths = loops.Select(loop => loop.ProjectTo2DCoordinates(transform, 0, true));
            // the basePlaneDistance defines the plane closer to the origin. we can get this from the any input coordinate
            var basePlaneDistance = extrudeDirection.Dot(loops.First().First());

            if (midPlane)
            {
                basePlaneDistance -= extrusionHeight / 2.0;
            }
            var polygons = paths.CreateShallowPolygonTrees(false);

            return(polygons.SelectMany(polygon => Extrude.ExtrusionFacesFrom2DPolygons(polygon,
                                                                                       extrudeDirection, basePlaneDistance, extrusionHeight)).ToList());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create the triangular faces of an extruded solid from 2D paths.
        /// </summary>
        /// <param name="paths">The paths.</param>
        /// <param name="basePlaneNormal">The base plane normal.</param>
        /// <param name="basePlaneDistance">The base plane distance.</param>
        /// <param name="extrusionHeight">Height of the extrusion.</param>
        /// <returns>List&lt;PolygonalFace&gt;.</returns>
        public static List <PolygonalFace> ExtrusionFacesFrom2DPolygons(this IEnumerable <IEnumerable <Vector2> > paths, Vector3 basePlaneNormal,
                                                                        double basePlaneDistance, double extrusionHeight)
        {
            var polygons = paths.CreateShallowPolygonTrees(false);

            return(polygons.SelectMany(polygon => Extrude.ExtrusionFacesFrom2DPolygons(polygon,
                                                                                       basePlaneNormal, basePlaneDistance, extrusionHeight)).ToList());
        }
Exemplo n.º 3
0
 /// <summary>
 ///     Sets the Solid Representation of the bounding box
 /// </summary>
 public void SetSolidRepresentation()
 {
     if (CornerVertices == null || !CornerVertices.Any())
     {
         SetCornerVertices();
     }
     SolidRepresentation = Extrude.FromLoops(new List <List <Vertex> >()
     {
         CornerVertices.Take(4).ToList()
     }, Directions[2], Dimensions[2]);
 }
Exemplo n.º 4
0
        //public void SetVolume()
        //{
        //    Volume = 0.0;
        //    for (var i = 0; i < NumLayers - 1; i++) //Include the last index, since we already modified start or stop
        //    {
        //        if (Layer2D[i] == null || !Layer2D[i].Any() || Layer2D[i + 1] == null || !Layer2D[i + 1].Any()) continue;
        //        var halfThickness = 0.5 * (StepDistances[i + 1] - StepDistances[i]);
        //        Volume += halfThickness * (Layer2D[i].Sum(p => p.Area) + Layer2D[i].Sum(p => p.Area));
        //    }
        //}

        /// <summary>
        /// Layer2D and 3D can be indexed in the forward or reverse order from the step distances.
        /// This can be useful when working in a bi-directional scope. In both cases, it will start
        /// by extruding the first valid loop in Layer3D and stop before extruding the last one (the
        /// n-1 extrusion will have ended on at the distance of the final cross section).
        /// If reversed, it will simply extrude backward instead of forward.
        /// </summary>
        public IReadOnlyCollection <PolygonalFace> ConvertToTessellatedExtrusions(bool extrudeBack = true)
        {
            if (!Layer3D.Any())
            {
                SetAllVertices();
            }
            var start     = Layer3D.Where(p => p.Value.Any()).FirstOrDefault().Key;
            var stop      = Layer3D.Where(p => p.Value.Any()).LastOrDefault().Key;
            var reverse   = start < stop ? 1 : -1;
            var direction = reverse == 1 ? Direction : Direction.multiply(-1);
            var faces     = new List <PolygonalFace>();

            //If extruding back, then we skip the first loop, and extrude backward from the remaining loops.
            //Otherwise, extrude the first loop and all other loops forward, except the last loop.
            //Which of these extrusion options you choose depends on how the cross sections were defined.
            //But both methods, only result in material between the cross sections.
            if (extrudeBack)
            {
                direction = direction.multiply(-1);
                start    += reverse;
            }
            else
            {
                stop -= reverse;
            }
            for (var i = start; i *reverse <= stop *reverse; i += reverse)   //Include the last index, since we already modified start or stop
            {
                if (!Layer3D[i].Any())
                {
                    continue;                    //THere can be gaps in layer3D if this actually represents more than one solid body
                }
                double distance;
                if (extrudeBack)
                {
                    distance = Math.Abs(StepDistances[i] - StepDistances[i - reverse]);             //current - prior (reverse extrusion)
                }
                else
                {
                    distance = Math.Abs(StepDistances[i + reverse] - StepDistances[i]);  //next - current (forward extrusion)
                }
                var layerfaces = Extrude.ReturnFacesFromLoops(Layer3D[i], direction, distance, false);
                if (layerfaces == null)
                {
                    continue;
                }
                faces.AddRange(layerfaces);
            }
            return(faces);
        }