public Polygon Clip(Polygon clippingPoly, ClipType type = ClipType.ctIntersection)
        {
            List <List <IntPoint> > list = new List <List <IntPoint> >();

            list.Add(GetPath());
            List <List <IntPoint> > list2 = new List <List <IntPoint> >();

            list2.Add(clippingPoly.GetPath());
            Clipper  clipper  = new Clipper(0);
            PolyTree polytree = new PolyTree();

            clipper.AddPaths(list, PolyType.ptSubject, true);
            clipper.AddPaths(list2, PolyType.ptClip, true);
            clipper.Execute(type, polytree, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);
            List <List <IntPoint> > list3 = Clipper.PolyTreeToPaths(polytree);

            if (list3.Count > 0)
            {
                List <Vector2> list4 = new List <Vector2>();
                for (int i = 0; i < list3[0].Count; i++)
                {
                    List <Vector2> list5     = list4;
                    IntPoint       intPoint  = list3[0][i];
                    float          x         = (float)intPoint.X * 0.0001f;
                    IntPoint       intPoint2 = list3[0][i];
                    list5.Add(new Vector2(x, (float)intPoint2.Y * 0.0001f));
                }
                return(new Polygon(list4));
            }
            return(null);
        }
Esempio n. 2
0
        public static bool addSteinerPointsAtOffset(ref Polygon _polygon, ref ClipperOffset co, float offset, int seglenBigInt)
        {
            PolyTree resPolytree = new AXClipperLib.PolyTree();

            co.Execute(ref resPolytree, (double)(-offset * AXGeometryTools.Utilities.IntPointPrecision));
            Paths paths = Clipper.PolyTreeToPaths(resPolytree);

            if (paths != null && paths.Count > 0 && paths[0] != null && paths[0].Count > 0)
            {
                foreach (Path path in paths)
                {
                    if (path != null && path.Count > 0)
                    {
                        Path ppp = Pather.segmentPath(path, seglenBigInt);
                        if (ppp != null && ppp.Count > 0)
                        {
                            foreach (IntPoint ip in ppp)
                            {
                                _polygon.AddSteinerPoint(new TriangulationPoint((double)ip.X / (double)AXGeometryTools.Utilities.IntPointPrecision, (double)ip.Y / (double)AXGeometryTools.Utilities.IntPointPrecision));
                            }
                        }
                    }
                }


                return(true);
            }
            return(false);
        }
Esempio n. 3
0
        private IEnumerable <CPolygon> GrowAndClipMergedCpg_Overlap(CPolygon mergedcpg,
                                                                    double dblProp, string strSimplification, string strBufferStyle, double dblMiterLimit)
        {
            //dblProp = 0.2;
            //dblProp = 1;
            double dblCurrentScale   = _dblStartScale + dblProp * (_dblTargetScale - _dblStartScale);
            double dblCurrentGrow    = dblProp * _dblTotalGrow * CConstants.dblFclipper;
            double dblCurrentEpsilon = Math.Min(dblCurrentGrow / dblMiterLimit, _dblEpsilon * dblCurrentScale * CConstants.dblFclipper);
            double dblCurrentErosion = _dblErosion * dblCurrentScale * CConstants.dblFclipper;

            //double dblCurrentDilation = Math.Max(dblCurrentEpsilon / 2, dblProp * _dblDilation * dblCurrentScale * CConstants.dblFclipper);
            double dblCurrentDilation = (dblCurrentGrow - dblMiterLimit * dblCurrentErosion) / (dblMiterLimit - 1);
            //dblCurrentErosion = 0;
            //dblCurrentDilation = 0;

            var clipPathsFirstLevel = clipperMethods.GenerateClipPathsByCpgEb(mergedcpg.ClipCpgLt);
            var LastAndClippedPath  = new Paths();

            if (mergedcpg.SubCpgLt == null || mergedcpg.SubCpgLt.Count < 2)
            {
                LastAndClippedPath.AddRange(DilateErodeOffsetSimplifyCpg(mergedcpg,
                                                                         dblCurrentGrow, dblCurrentDilation, dblCurrentErosion, dblCurrentEpsilon,
                                                                         strSimplification, strBufferStyle, dblMiterLimit));
            }
            else
            {
                //var SubCpgLt = mergedcpg.SubCpgLt;
                var submergedcpglt = MergeCloseCpgsAndAddBridges(mergedcpg.SubCpgLt, false,  //---Merge---//
                                                                 dblCurrentGrow, dblCurrentDilation, dblCurrentEpsilon);
                //var BridgeCpipeDt = mergedcpg.BridgeCpipeDt;
                foreach (var submergedcpg in submergedcpglt)
                {
                    LastAndClippedPath.AddRange(DilateErodeOffsetSimplifyCpg(submergedcpg,
                                                                             dblCurrentGrow, dblCurrentDilation, dblCurrentErosion, dblCurrentEpsilon,
                                                                             strSimplification, strBufferStyle, dblMiterLimit));
                }
            }

            //CSaveFeature.SaveCEdgeEb(clipperMethods.ScaleCEdgeEb(
            //    clipperMethods.ConvertPathsToCEdgeEb(LastAndClippedPath, true), 1 / CConstants.dblFclipper),
            //    "GrownPathsWithoutMergeOrClip", blnVisible: false);

            LastAndClippedPath.AddRange(mergedcpg.LastTimePaths);
            var unitedPaths = clipperMethods.Clip_Paths(LastAndClippedPath, true, mergedcpg.LastTimePaths, true, ClipType.ctUnion);
            //var unitedPaths = LastAndClippedPath;

            var clippedPolyTree =
                clipperMethods.Clip_PolyTree(unitedPaths, true, clipPathsFirstLevel, true, ClipType.ctIntersection);

            mergedcpg.LastTimePaths = Clipper.PolyTreeToPaths(clippedPolyTree);
            var GrownAndClippedCpg = clipperMethods.GenerateCpgEbByPolyTree(clippedPolyTree, mergedcpg.ID, true);

            //CSaveFeature.SavePolyTreeAsCpgEb(clippedPolyTree, "GrownMergeClipPolyTree",
            //    pesriSimpleFillStyle: esriSimpleFillStyle.esriSFSNull, blnVisible: false);

            return(GrownAndClippedCpg);
        }
Esempio n. 4
0
        public float Area()
        {
            float area = 0;

            foreach (var poly in Clipper.PolyTreeToPaths(polyTree))
            {
                area += (float)Clipper.Area(poly);
            }
            return(area);
        }
Esempio n. 5
0
        public void Union(Slice other)
        {
            Clipper c = new Clipper();

            c.Clear();
            c.AddPaths(Clipper.PolyTreeToPaths(polyTree), PolyType.ptSubject, true);
            c.AddPaths(Clipper.PolyTreeToPaths(other.polyTree), PolyType.ptClip, true);

            polyTree = new PolyTree();
            c.Execute(ClipType.ctUnion, polyTree);
        }
Esempio n. 6
0
        public void Subtract(Slice other)
        {
            Clipper c = new Clipper();

            c.Clear();
            c.AddPaths(Clipper.PolyTreeToPaths(polyTree), PolyType.ptSubject, true);
            c.AddPaths(Clipper.PolyTreeToPaths(other.polyTree), PolyType.ptClip, true);

            polyTree = new PolyTree();
            c.Execute(ClipType.ctDifference, polyTree);
        }
Esempio n. 7
0
        public bool Contains(Slice other)
        {
            // To contain another slice:
            // 1. Area of the union must be the same
            // 2. Area of this - other must be less



            float thisArea = this.Area();

            Paths   otherPolygons = Clipper.PolyTreeToPaths(other.polyTree);
            Paths   thesePolygons = Clipper.PolyTreeToPaths(polyTree);
            Slice   s             = new Slice(this);
            Clipper c             = new Clipper();

            c.Clear();
            c.AddPaths(thesePolygons, PolyType.ptSubject, true);
            c.AddPaths(otherPolygons, PolyType.ptClip, true);
            s.polyTree = new PolyTree();
            c.Execute(ClipType.ctUnion, s.polyTree);
            float area_union = s.Area();

            if (area_union > thisArea)
            {
                return(false);
            }
            return(true);
            //c.Clear();
            //c.AddPaths(thesePolygons, PolyType.ptSubject, true);
            //c.AddPaths(otherPolygons, PolyType.ptClip, true);
            //s.polyTree = new PolyTree();
            //c.Execute(ClipType.ctDifference, s.polyTree);
            //float area_difference = s.Area();
            //if (area_difference < thisArea)
            //{
            //    return true;
            //}
            //return false;
        }
Esempio n. 8
0
    public static void DrawPathsFit(AXParameter p, Vector2 offset, float size, Color color)
    {
        if (p == null)
        {
            return;
        }

        bool isClosed = (p.shapeState == ShapeState.Closed || p.thickness > 0);

        float rot = 0;        //p.Parent.floatValue("Rot_Z");


        Paths paths = null;

        if (p.polyTree != null)
        {
            paths = Clipper.PolyTreeToPaths(p.polyTree);
        }
        else if (p.paths != null)
        {
            paths = p.paths;
        }



        Rect  t_bounds = AXGeometryTools.Utilities.getClipperBounds(p.transformedControlPaths);
        float t_maxdim = (t_bounds.width > t_bounds.height) ? t_bounds.width : t_bounds.height;
        float t_scale  = size / t_maxdim;

        Rect  p_bounds = AXGeometryTools.Utilities.getClipperBounds(paths);
        float p_maxdim = (p_bounds.width > p_bounds.height) ? p_bounds.width : p_bounds.height;
        float p_scale  = size / p_maxdim;

        float scale  = t_scale;
        Rect  bounds = t_bounds;

        if (p_scale < t_scale)
        {
            scale  = p_scale;
            bounds = p_bounds;
        }
        offset += scale * new Vector2(-(bounds.x + bounds.width / 2), bounds.y + bounds.height / 2);

        // DRAW CONTROL_PATHS control paths
        //if(p.transformedControlPaths != null)
        if (p.transformedButUnscaledOutputPaths != null)
        {
            foreach (Path cpath in p.transformedButUnscaledOutputPaths)
            {
                drawPath(AXGeometryTools.Utilities.path2Vec2s(cpath, rot, scale), offset, isClosed, Color.gray);
            }
        }

        if (p.transformedAndScaledButNotOffsetdOutputPaths != null)
        {
            foreach (Path cpath in p.transformedAndScaledButNotOffsetdOutputPaths)
            {
                drawPath(AXGeometryTools.Utilities.path2Vec2s(cpath, rot, scale), offset, isClosed, Color.cyan);
            }
        }

        if (paths != null)
        {
            foreach (Path path in paths)
            {
                drawPath(AXGeometryTools.Utilities.path2Vec2s(path, rot, scale), offset, isClosed, color);
            }
        }


        // axis
        Vector2[] xaxis = new Vector2[2];
        xaxis[0] = new Vector2(-5, 0);
        xaxis[1] = new Vector2(5, 0);

        Vector2[] yaxis = new Vector2[2];
        yaxis[0] = new Vector2(0, -5);
        yaxis[1] = new Vector2(0, 5);

        drawPath(xaxis, offset, false, Color.gray);
        drawPath(yaxis, offset, false, Color.gray);
    }
Esempio n. 9
0
        public static void thickenAndOffset(ref AXParameter sp, AXParameter src)
        {
            if (sp == null || src == null)
            {
                return;
            }
            //sp.polyTree = null;



            float thickness = sp.thickness;
            float roundness = sp.roundness;
            float offset    = sp.offset;
            bool  flipX     = sp.flipX;

            //Debug.Log(sp.parametricObject.Name + "." + sp.Name +"."+ sp.offset);

            //bool srcIsCC = src.isCCW();



            Paths subjPaths = src.getClonePaths();

            if (subjPaths == null)
            {
                return;
            }


            // FLIP_X
            if (flipX)
            {
                //Debug.Log(subjPaths.Count);
                //AXGeometryTools.Utilities.printPaths(subjPaths);

                subjPaths = AXGeometryTools.Utilities.transformPaths(subjPaths, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, 1)));

                sp.transformedControlPaths = AXGeometryTools.Utilities.transformPaths(sp.transformedControlPaths, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, 1)));
            }



            // SYMMETRY
            if (sp.symmetry)
            {
                if (subjPaths != null && subjPaths.Count > 0)
                {
                    for (int i = 0; i < subjPaths.Count; i++)
                    {
                        Path orig = subjPaths[i];

                        Path sym = new Path();

                        float seperation = sp.symSeperation * AXGeometryTools.Utilities.IntPointPrecision;
                        float apex       = .1f * seperation;


                        for (int j = 0; j < orig.Count; j++)
                        {
                            sym.Add(new IntPoint(orig[j].X + seperation / 2, orig[j].Y));
                        }

                        // midpoint. slightly raised
                        sym.Add(new IntPoint(0, orig[orig.Count - 1].Y + apex));

                        for (int j = orig.Count - 1; j >= 0; j--)
                        {
                            sym.Add(new IntPoint(-orig[j].X - seperation / 2, orig[j].Y));
                        }

                        subjPaths[i] = sym;
                    }
                }
            }



            AX.Generators.Generator2D gener2D = sp.parametricObject.generator as AX.Generators.Generator2D;


            if (subjPaths != null && gener2D != null && (gener2D.scaleX != 1 || gener2D.scaleY != 1))
            {
                sp.transformedButUnscaledOutputPaths = AX.Generators.Generator2D.transformPaths(subjPaths, gener2D.localUnscaledMatrix);
            }
            else
            {
                sp.transformedButUnscaledOutputPaths = null;
            }



            //cleanPolygonPrecision
            IntRect brect = Clipper.GetBounds(subjPaths);

            if ((brect.right - brect.left) < 10000)
            {
                cleanPolygonPrecision = 2;
            }
            else
            {
                cleanPolygonPrecision = 30;
            }

            //Debug.Log("cleanPolygonPrecision="+cleanPolygonPrecision);

            /*
             * if (offset_p.FloatVal == 0 && wallthick_p.FloatVal == 0)
             * {
             *      sp.polyTree = src.polyTree;
             *      sp.paths = src.paths;
             *      return;
             * }
             *
             */
            //sp.polyTree = null;



            //Debug.Log("new count a = " + subjPaths[0].Count);


            bool hasOffset = false;

            sp.hasThickness = false;


            Paths resPaths = new Paths();

            AXClipperLib.PolyTree resPolytree = null;

            ClipperOffset co = new ClipperOffset();


            //co.ArcTolerance = sp.arcTolerance;
            float smooth    = (float)(120 / (sp.arcTolerance * sp.arcTolerance));
            float smoothLOD = ((smooth - .048f) * sp.parametricObject.model.segmentReductionFactor) + .048f;

            co.ArcTolerance = (float)(Mathf.Sqrt(120 / smoothLOD));


            co.MiterLimit = 2.0f;


            //if (offset != 0)


            // 1. Offset? Can't offset an open shape
            if (sp.shapeState == ShapeState.Closed && (sp.endType == AXClipperLib.EndType.etClosedLine || sp.endType == AXClipperLib.EndType.etClosedPolygon))
            {
                //AXClipperLib.JoinType jt = (sp.endType == AXClipperLib.EndType.etClosedLine) ? JoinType.jtMiter : sp.joinType;//output.joinType;
                AXClipperLib.JoinType jt = (sp.parametricObject.model.segmentReductionFactor < .15f) ? AXClipperLib.JoinType.jtSquare  : sp.joinType;                //output.joinType;
                //Debug.Log ("sp.endType="+sp.endType+", jt="+jt);

                if (roundness != 0)
                {
                    // reduce
                    co.Clear();

                    if (subjPaths != null)
                    {
                        co.AddPaths(AXGeometryTools.Utilities.cleanPaths(subjPaths, cleanPolygonPrecision), jt, AXClipperLib.EndType.etClosedPolygon);                           //JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon);
                    }
                    co.Execute(ref subjPaths, (double)(-roundness * AXGeometryTools.Utilities.IntPointPrecision));
                }

                offset += roundness;

                if (subjPaths != null)
                {
                    subjPaths = Clipper.SimplifyPolygons(subjPaths, PolyFillType.pftNonZero);
                }

                co.Clear();

                hasOffset = true;

//				if (offset != 0 || thickness == 0) { // --! PUC ** Removed because the pass thru was causing a problem with Instance2D of a ShapeMerger
                // Do Offset

                // = true;

                if (subjPaths != null)
                {
                    // After changes made mid April to allow for FlipX, this started doubling the localMatrix and thus became redundent, though not sure why.
                    //if (gener2D != null)
                    //	sp.transformedAndScaledButNotOffsetdOutputPaths = AX.Generators.Generator2D.transformPaths(subjPaths, gener2D.localMatrix);

                    co.AddPaths(AXGeometryTools.Utilities.cleanPaths(subjPaths, cleanPolygonPrecision), jt, AXClipperLib.EndType.etClosedPolygon);                              //JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon);

                    // this resPolytree has transformed curves in it
                    resPolytree = new AXClipperLib.PolyTree();
                    co.Execute(ref resPolytree, (double)(offset * AXGeometryTools.Utilities.IntPointPrecision));
                }
//				}
                if (thickness > 0)
                {                       // No offset, but is closed
                    sp.transformedAndScaledButNotOffsetdOutputPaths = null;
                    if (src.polyTree != null)
                    {
                        if (thickness > 0)
                        {
                            resPaths = subjPaths;                             // Clipper.PolyTreeToPaths(src.polyTree);
                        }
                        else
                        {
                            resPolytree = src.polyTree;
                        }
                    }
                    else
                    {
                        resPaths = subjPaths;
                    }
                }
            }
            else
            {
                //resPolytree = src.polyTree;
                if (src.polyTree != null)
                {
                    if (thickness > 0)
                    {
                        resPaths = subjPaths;                         // Clipper.PolyTreeToPaths(src.polyTree);
                    }
                    else
                    {
                        resPolytree = src.polyTree;
                    }
                }
                else
                {
                    resPaths = subjPaths;
                }
            }


            // 2. Thickness?
            //subjPaths = sp.getPaths();


            if ((sp.endType != AXClipperLib.EndType.etClosedPolygon) && thickness > 0)              //input.endType != AXClipperLib.EndType.etClosedPolygon) {
            {
                // this is a wall
                if (resPaths != null && gener2D != null)
                {
                    sp.transformedFullyAndOffsetdButNotThickenedOutputPaths = AX.Generators.Generator2D.transformPaths(resPaths, gener2D.localMatrix);
                }

                sp.hasThickness = true;


                co.Clear();
                if (resPolytree != null)                                                                                                                     // closed block has happened
                {
                    co.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(resPolytree), cleanPolygonPrecision), sp.joinType, sp.endType); //input.endType);
                }
                else if (resPaths != null)
                {
                    co.AddPaths(AXGeometryTools.Utilities.cleanPaths(resPaths, cleanPolygonPrecision), sp.joinType, sp.endType);                     //input.endType);
                }

                resPolytree = new AXClipperLib.PolyTree();
                co.Execute(ref resPolytree, (double)(thickness * AXGeometryTools.Utilities.IntPointPrecision));
            }
            else
            {
                sp.transformedFullyAndOffsetdButNotThickenedOutputPaths = null;
            }



            // 3. Update input data
            //Debug.Log(sp.parametricObject.Name  + "." + sp.Name + " here ["+hasOffset+"] " + (! sp.symmetry) + " " +  (! flipX)  + " " + (! hasOffset)  + " " +  (! hasThicken)  + " " +  (roundness == 0));


            // SIMPLE PASSTHRU?
            if (!sp.symmetry && !flipX && !hasOffset && !sp.hasThickness && roundness == 0)
            {
                // SIMPLE PASS THROUGH
                sp.polyTree = src.polyTree;
                sp.paths    = src.paths;
            }

            else
            {
                if (resPolytree == null)
                {
                    //sp.paths      = resPaths; //Generator2D.transformPaths(resPaths, gener2D.localMatrix);
                    //if (Clipper.Orientation(resPaths[0]) != srcIsCC)
                    //	AXGeometryTools.Utilities.reversePaths(ref resPaths);

                    sp.paths = AXGeometryTools.Utilities.cleanPaths(resPaths, cleanPolygonPrecision);
                }
                else
                {
                    //Generator2D.transformPolyTree(resPolytree, gener2D.localMatrix);

                    //if (resPolytree != null && resPolytree.Childs.Count > 0 &&  Clipper.Orientation(resPolytree.Childs[0].Contour) != srcIsCC)
                    //	AXGeometryTools.Utilities.reversePolyTree(resPolytree);


                    sp.polyTree = resPolytree;
                }
            }



            // REVERSE
            if (sp.reverse)
            {
                if (sp.polyTree != null)
                {
                    AXGeometryTools.Utilities.reversePolyTree(sp.polyTree);
                }
                else if (sp.paths != null && sp.paths.Count > 0)
                {
                    for (int i = 0; i < sp.paths.Count; i++)
                    {
                        sp.paths[i].Reverse();
                    }
                }
            }



//			if (sp.paths != null && sp.paths.Count > 0)
//			{
//				// SUBDIVISION
//				Debug.Log("sp.paths.Count="+sp.paths.Count);
//
//				for(int i=0; i<sp.paths.Count; i++)
//				{
//
//
//					Path path = sp.paths[i];
//					Path subdivPath = new Path();
//
//					for (int j=0; j<path.Count-1; j++)
//					{
//						subdivPath.Add(path[j]);
//						Vector2 v0 = new Vector2(path[j].X, path[j].Y);
//						Vector2 v1 = new Vector2(path[j+1].X, path[j+1].Y);
//
//						Debug.Log("["+i+"]["+j+"] " + Vector2.Distance(v0, v1)/10000);
//						 Vector2 newp = Vector2.Lerp(v0, v1, .5f);
//
//						subdivPath.Add(new IntPoint(newp.x, newp.y));
//					}
//					subdivPath.Add(path[path.Count-1]);
//
//
//					sp.paths[i] = subdivPath;
//
//					Debug.Log("------------");
//					AXGeometryTools.Utilities.printPath(sp.paths[i]);
//				}
//					// SUBDIVISION ---
//			}
//
        }
Esempio n. 10
0
        /* GENERATE LINE */

        public void generateLine()
        {
            if (inputs.Count == 0)
            {
                return;
            }

            Clipper c = new Clipper(Clipper.ioPreserveCollinear);

            c.PreserveCollinear = true;
            AXParameter input = null;
            AXParameter src   = null;

            //Debug.Log ("GENERATE LINE");


//			// DON'T ALTER AN "OPEN" SHAPE OR RAIL IF IT IS NOT BEING COMBINED WITH OTHER INPUTS AND IS NOT THICKENED OR OFFSET
            if (inputs.Count == 1 && inputs[0].offset == 0 && inputs[0].thickness == 0)
            {
                if (inputs[0].DependsOn != null)
                {
                    difference.polyTree = inputs[0].DependsOn.polyTree;
                    difference.paths    = inputs[0].DependsOn.paths;
                }


                //Archimatix.printPath(output.paths[0]);
                return;
            }

            // GROUPED COMBINE
            grouped.paths = new Paths();
            foreach (AXParameter inp in inputs)
            {
                if (inp.paths == null)
                {
                    continue;
                }

                foreach (Path _path in inp.paths)
                {
                    grouped.paths.Add(_path);
                }
            }


            // EACH INPUT (PREPROCESSING)

            for (int i = 0; i < inputs.Count; i++)
            {
                input = inputs [i];
                src   = input.DependsOn;

                if (src != null && src.parametricObject != null && !src.parametricObject.isActive)
                {
                    continue;
                }

                if (src == null)
                {
                    continue;
                }
                input.polyTree = null;

                thickenAndOffset(ref input, src);

                // Add as a Solid or Void (subj or clip) to Clipper c
                //bool isClosed = (input.shapeState == ShapeState.Closed || input.polyType == PolyType.ptSubject) ? true : false;
                bool isClosed = true;
                if (input.polyTree != null)
                {
                    c.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(input.polyTree)), input.polyType, isClosed);
                }
                else if (input.paths != null)
                {
                    c.AddPaths(AXGeometryTools.Utilities.cleanPaths(input.paths), input.polyType, isClosed);
                }
            }             // end inputs preprocessing



            // COMBINE INPUTS

            // Output

            AX.Generators.Generator2D gener2D = parametricObject.generator as AX.Generators.Generator2D;

            // DIFFERENCE

            if ((difference.Dependents != null && difference.Dependents.Count > 0) || combineType == CombineType.Difference)
            {
                difference.polyTree = new AXClipperLib.PolyTree();
                c.Execute(ClipType.ctDifference, difference.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);


                thickenAndOffset(ref difference, difference);


                AXGeometryTools.Utilities.transformPolyTree(difference.polyTree, gener2D.localMatrix);

                if (difference.reverse)
                {
                    AXGeometryTools.Utilities.reversePolyTree(difference.polyTree);
                }

                AX.Generators.Generator2D.deriveStatsETC(difference);
            }

            // INTERSECTION
            //if((intersection.Dependents != null && intersection.Dependents.Count > 0) || combineType == CombineType.Intersection)
            //{
            intersection.polyTree = new AXClipperLib.PolyTree();
            c.Execute(ClipType.ctIntersection, intersection.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);


            thickenAndOffset(ref intersection, intersection);

            AXGeometryTools.Utilities.transformPolyTree(intersection.polyTree, gener2D.localMatrix);

            if (intersection.reverse)
            {
                AXGeometryTools.Utilities.reversePolyTree(intersection.polyTree);
            }

            AX.Generators.Generator2D.deriveStatsETC(intersection);

            //}

            // UNION
            if ((union.Dependents != null && union.Dependents.Count > 0) || combineType == CombineType.Union)
            {
                union.polyTree = new AXClipperLib.PolyTree();
                c.Execute(ClipType.ctUnion, union.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);


                thickenAndOffset(ref union, union);

                AXGeometryTools.Utilities.transformPolyTree(intersection.polyTree, gener2D.localMatrix);

                if (union.reverse)
                {
                    AXGeometryTools.Utilities.reversePolyTree(union.polyTree);
                }

                AX.Generators.Generator2D.deriveStatsETC(union);
            }
        }
Esempio n. 11
0
        /*
         * public override void initializeBays(string pName)
         * {
         *      if (parametricObject.isInitialized)
         *              return;
         *
         *      parametricObject.isInitialized = true;
         *
         *      RadialRepeaterTool gener = repeaterToolU as RadialRepeaterTool;
         *
         *      switch(pName)
         *      {
         *      case "Node Shape":
         *              if (repeaterToolU != null)
         *                      gener.radius = 3.5f * nodeSrc_p.parametricObject.bounds.size.x ;
         *              break;
         *      case "Cell Shape":
         *              if (repeaterToolU != null)
         *                      gener.radius = 2.5f * cellSrc_p.parametricObject.bounds.size.x ;
         *              break;
         *      }
         * }
         */



        // SHAPE_REPEATER_2D :: GENERATE
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica)
        {
            if (parametricObject == null || !parametricObject.isActive)
            {
                return(null);
            }

            if ((P_Corner == null || cornerSrc_p == null) && (P_Node == null || inputSrc_p == null) && (P_Cell == null || cellSrc_p == null))
            {
                if (P_Output != null)
                {
                    P_Output.paths    = null;
                    P_Output.polyTree = null;
                }
                return(null);
            }


            // PRE_GENERATE
            preGenerate();


            planSrc_p  = P_Plan.DependsOn;                         // getUpstreamSourceParameter(P_Plan);
            planSrc_po = (planSrc_p != null)                                                           ? planSrc_p.parametricObject    : null;


            P_Plan.polyTree = null;
            AXShape.thickenAndOffset(ref P_Plan, planSrc_p);
            if (P_Plan.reverse)
            {
                P_Plan.doReverse();
            }


            planPaths = P_Plan.getPaths();

            if (planPaths == null || planPaths.Count == 0)
            {
                return(null);
            }



            // ** CREATE PLAN_SPLINES **

            if (planPaths != null && planPaths.Count > 0)
            {
                planSplines = new Spline[planPaths.Count];


                if (planSplines != null)
                {
                    for (int i = 0; i < planSplines.Length; i++)
                    {
                        planSplines[i] = new Spline(planPaths[i], (P_Plan.shapeState == ShapeState.Closed) ? true : false);
                    }
                }
            }



            AXParameter P_cornerOutput = new AXParameter();

            P_cornerOutput.parametricObject = parametricObject;

            AXParameter P_nodeOutput = new AXParameter();

            P_nodeOutput.parametricObject = parametricObject;


            AXParameter P_cellOutput = new AXParameter();

            P_cellOutput.parametricObject = parametricObject;



            // PROCESS SHAPE INPUTS

            if (cornerSrc_p != null)
            {
                P_Corner.polyTree = null;
                AXShape.thickenAndOffset(ref P_Corner, cornerSrc_p);
            }

            if (inputSrc_p != null)
            {
                P_Node.polyTree = null;
                AXShape.thickenAndOffset(ref P_Node, inputSrc_p);
            }


            if (cellSrc_p != null)
            {
                P_Cell.polyTree = null;
                AXShape.thickenAndOffset(ref P_Cell, cellSrc_p);
            }



            bool doPolyTreeNodes = false;
            //bool doPolyTreeCells = false;


            // NODE
            //Matrix4x4 tm = Matrix4x4.identity;



            //  NODE SHAPES
            Paths nodeSourcePaths = null;

            //Clipper nodeClipper = null;

            if (P_Node != null)
            {
                if (P_Node.polyTree != null)
                {
                    nodeSourcePaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Node.polyTree));
                    doPolyTreeNodes = true;
                    //nodeClipper =  new Clipper();
                }
                else
                {
                    nodeSourcePaths    = P_Node.getClonePaths();
                    P_nodeOutput.paths = new Paths();
                }
            }


            // CELL SHAPES
            Paths cellSourcePaths = null;

            //Clipper cellClipper = null;

            if (P_Cell != null)
            {
                if (P_Cell.polyTree != null)
                {
                    cellSourcePaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Cell.polyTree));
                    doPolyTreeNodes = true;
                    //cellClipper =  new Clipper();
                }
                else
                {
                    cellSourcePaths      = P_Cell.getClonePaths();
                    P_cornerOutput.paths = new Paths();
                }
            }



            // BREAK CORNER SHAPES
            Paths   cornerSourcePaths = null;
            Clipper cornerClipper     = null;

            if (P_Corner != null)
            {
                if (P_Corner.polyTree != null)
                {
                    cornerSourcePaths = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Corner.polyTree));
                    doPolyTreeNodes   = true;
                    cornerClipper     = new Clipper();
                }
                else
                {
                    cornerSourcePaths    = P_Corner.getClonePaths();
                    P_cornerOutput.paths = new Paths();
                }
            }



            // FOR EACH PATH

            for (int path_i = 0; path_i < planPaths.Count; path_i++)
            {
                // **** PREPARE EACH SPLINE *** //

                Spline planSpline = planSplines[path_i];

                planSpline.breakAngleCorners = cornerBreakAngle;
                planSpline.shapeState        = P_Plan.shapeState;

                // Create subsplines between each break point
                planSpline.getSmoothSubsplineIndicies(0, maxSegmentLength);

//					Debug.Log("planSpline.subsplines.Count="+ planSpline.subsplines.Count );
//					foreach(SubsplineIndices si in planSpline.subsplines)
//						si.print();

                planSpline.groupNearBreakAngleVertices(inset * 2);

                // **** PREPARE EACH SPLINE *** //



                Matrix4x4 localPlacement_mx = Matrix4x4.identity;



                if (planSpline.insetSpanSplines != null && planSpline.insetSpanSplines.Count > 0)
                {
                    for (int si = 0; si < planSpline.insetSpanSplines.Count; si++)
                    {
                        planSpline.insetSpanSplines[si].setRepeaterTransforms(si, inset, bay);
                    }



                    // SPAN NODES - SHAPES ALONG SUBSPLINES
                    if (nodeSrc_p != null && nodeSrc_p.meshes != null)
                    {
                        int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ?  planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count;

                        for (int i = 0; i < endCount; i++)
                        {
                            //SubsplineIndices rsi = planSpline.subsplines[i];
                            Spline           spanSpline   = planSpline.insetSpanSplines[i];
                            List <Matrix4x4> nodeMatrices = spanSpline.repeaterNodeTransforms;


                            // on each of these nodes, place a nodePlug instance.
                            bool spanNodesAtBreakCorners = true;

                            int starter = spanNodesAtBreakCorners ? 0 : 1;
                            int ender   = (inset > 0 || spanNodesAtBreakCorners) ? nodeMatrices.Count : nodeMatrices.Count - 1;

                            //string this_address = "";


                            if (nodeMatrices != null)
                            {
                                for (int ii = starter; ii < ender; ii++)
                                {
                                    //this_address = "node_"+path_i+"_"+i+"_"+ii;

                                    //Debug.Log("this_address="+this_address);
                                    // LOCAL_PLACEMENT

                                    localPlacement_mx = localMatrixFromAddress(RepeaterItem.Node, path_i, i, ii);

                                    if (doPolyTreeNodes)
                                    {
                                        cornerClipper.AddPaths(AX.Generators.Generator2D.transformPaths(nodeSourcePaths, localPlacement_mx), PolyType.ptSubject, true);
                                    }
                                    else
                                    {
                                        Paths tmp = AX.Generators.Generator2D.transformPaths(nodeSourcePaths, localPlacement_mx);
                                        P_cornerOutput.paths.AddRange(tmp);
                                    }
                                }
                            }
                        }
                    }



                    // CELL NODES - SHAPES ALONG SUBSPLINES
                    if (cellSrc_p != null && cellSrc_p.meshes != null)
                    {
                        int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ?  planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count;

                        for (int i = 0; i < endCount; i++)
                        {
                            //SubsplineIndices rsi = planSpline.subsplines[i];
                            Spline           spanSpline   = planSpline.insetSpanSplines[i];
                            List <Matrix4x4> cellMatrices = spanSpline.repeaterCellTransforms;


                            // on each of these nodes, place a nodePlug instance.
                            bool spanNodesAtBreakCorners = true;

                            int starter = spanNodesAtBreakCorners ? 0 : 1;
                            int ender   = (inset > 0 || spanNodesAtBreakCorners) ? cellMatrices.Count : cellMatrices.Count - 1;

                            //string this_address = "";


                            if (cellMatrices != null)
                            {
                                for (int ii = starter; ii < ender; ii++)
                                {
                                    //this_address = "cell_"+path_i+"_"+i+"_"+ii;

                                    //Debug.Log("this_address="+this_address);
                                    // LOCAL_PLACEMENT

                                    localPlacement_mx = localMatrixFromAddress(RepeaterItem.Cell, path_i, i, ii);

                                    if (doPolyTreeNodes)
                                    {
                                        cornerClipper.AddPaths(AX.Generators.Generator2D.transformPaths(cellSourcePaths, localPlacement_mx), PolyType.ptSubject, true);
                                    }
                                    else
                                    {
                                        Paths tmp = AX.Generators.Generator2D.transformPaths(nodeSourcePaths, localPlacement_mx);
                                        P_cornerOutput.paths.AddRange(tmp);
                                    }
                                }
                            }
                        }
                    }
                }



                if (cornerSourcePaths != null && cornerSourcePaths.Count > 0)
                {
                    // CORNERS

                    for (int bi = 0; bi < planSpline.breakIndices.Count; bi++)
                    {
                        //tm = Matrix4x4.TRS(new Vector3(2*i-2, 2*j-2, 0), Quaternion.identity, Vector3.one);
                        localPlacement_mx = localMatrixFromAddress(RepeaterItem.Corner, path_i, planSpline.breakIndices[bi]);


                        if (doPolyTreeNodes)
                        {
                            cornerClipper.AddPaths(AX.Generators.Generator2D.transformPaths(cornerSourcePaths, localPlacement_mx), PolyType.ptSubject, true);
                        }
                        else
                        {
                            Paths tmp = AX.Generators.Generator2D.transformPaths(cornerSourcePaths, localPlacement_mx);
                            P_cornerOutput.paths.AddRange(tmp);
                        }
                    }
                }



                if (doPolyTreeNodes)
                {
                    P_cornerOutput.polyTree = new AXClipperLib.PolyTree();
                    cornerClipper.Execute(ClipType.ctDifference, P_cornerOutput.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
                }
            }



            P_Output.polyTree = null;

            if (cornerSrc_p != null || cellSrc_p == null || nodeSrc_p == null)
            {
                // JUST NODES
                AXShape.thickenAndOffset(ref P_Output, P_cornerOutput);
            }

            /*
             * else if (nodeSrc_p != null && (cellSrc_p == null || (P_cellOutput.paths == null && P_cellOutput.polyTree == null)))
             * {
             *      // JUST NODES
             *      AXShape.thickenAndOffset(ref P_Output, P_nodeOutput);
             * }
             *
             * else if (nodeSrc_p == null && cellSrc_p != null)
             * {
             *      // JUST CELLS
             *      AXShape.thickenAndOffset(ref P_Output, P_cellOutput);
             * }
             * else
             * {
             *      // BOTH TO COMBINE
             *      clipper =  new Clipper();
             *
             *      if (P_nodeOutput.polyTree == null)
             *              clipper.AddPaths(P_nodeOutput.paths, PolyType.ptSubject, true);
             *      else
             *              clipper.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_nodeOutput.polyTree)), PolyType.ptSubject, true);
             *
             *      if (P_cellOutput.polyTree == null)
             *              clipper.AddPaths(P_cellOutput.paths, PolyType.ptSubject, true);
             *      else
             *              clipper.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_cellOutput.polyTree)), PolyType.ptSubject, true);
             *
             *
             *      P_Output.polyTree = new AXClipperLib.PolyTree();
             *      clipper.Execute(ClipType.ctUnion,   P_Output.polyTree,  PolyFillType.pftNonZero, PolyFillType.pftNonZero);
             *
             *      AXShape.thickenAndOffset(ref P_Output, P_Output);
             * }
             */

            if (P_Output.polyTree != null)
            {
                transformPolyTree(P_Output.polyTree, localMatrix);
            }
            else if (P_nodeOutput.paths != null)
            {
                P_Output.paths = transformPaths(P_nodeOutput.paths, localMatrix);
                P_Output.transformedControlPaths = P_nodeOutput.paths;
            }
            //base.generate(false, initiator_po, isReplica);
            calculateBounds();

            return(null);
        }         // \generate
Esempio n. 12
0
        // SHAPE_REPEATER_2D :: GENERATE
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica)
        {
            if ((P_Node == null || inputSrc_p == null) && (P_Cell == null || cellSrc_p == null))
            {
                if (P_Output != null)
                {
                    P_Output.paths    = null;
                    P_Output.polyTree = null;
                }
                return(null);
            }

            if (repeaterToolU == null || repeaterToolV == null)
            {
                return(null);
            }

            // PRE_GENERATE
            preGenerate();



            AXParameter P_nodeOutput = new AXParameter();

            P_nodeOutput.parametricObject = parametricObject;


            AXParameter P_cellOutput = new AXParameter();

            P_cellOutput.parametricObject = parametricObject;



            // PROCESS NODE INPUT

            if (inputSrc_p != null)
            {
                P_Node.polyTree = null;
                AXShape.thickenAndOffset(ref P_Node, inputSrc_p);

                //P_nodeOutput.polyTree = null;
                //AXShape.thickenAndOffset(ref P_nodeOutput, P_Node);
            }

            if (cellSrc_p != null)
            {
                P_Cell.polyTree = null;
                AXShape.thickenAndOffset(ref P_Cell, cellSrc_p);

                //P_cellOutput.polyTree = null;
                //AXShape.thickenAndOffset(ref P_cellOutput, P_Cell);
            }



            bool doPolyTreeNodes = false;
            bool doPolyTreeCells = false;


            // NODE
            Matrix4x4 tm = Matrix4x4.identity;

            Paths tmpPaths = null;

            Clipper clipper = null;


            if (nodeSrc_p != null)
            {
                if (P_Node.polyTree != null)
                {
                    tmpPaths        = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Node.polyTree));
                    doPolyTreeNodes = true;
                    clipper         = new Clipper();
                }
                else
                {
                    tmpPaths           = P_Node.getClonePaths();
                    P_nodeOutput.paths = new Paths();
                }

                //Debug.Log("tmpPaths="+tmpPaths.Count);
                if (tmpPaths != null && tmpPaths.Count > 0)
                {
                    for (int i = 0; i <= repeaterToolU.cells; i++)
                    {
                        for (int j = 0; j <= repeaterToolV.cells; j++)
                        {
                            if ((i <= repeaterToolU.edgeCount || i >= repeaterToolU.cells - repeaterToolU.edgeCount) || (j <= repeaterToolV.edgeCount || j >= repeaterToolV.cells - repeaterToolV.edgeCount))
                            {
                                //tm = Matrix4x4.TRS(new Vector3(2*i-2, 2*j-2, 0), Quaternion.identity, Vector3.one);
                                tm = localMatrixFromAddress(RepeaterItem.Node, i, j);


                                if (doPolyTreeNodes)
                                {
                                    clipper.AddPaths(AX.Generators.Generator2D.transformPaths(tmpPaths, tm), PolyType.ptSubject, true);
                                }
                                else
                                {
                                    Paths tmp = AX.Generators.Generator2D.transformPaths(tmpPaths, tm);


                                    P_nodeOutput.paths.AddRange(tmp);
                                }
                            }
                        }
                    }

                    if (doPolyTreeNodes)
                    {
                        P_nodeOutput.polyTree = new AXClipperLib.PolyTree();
                        clipper.Execute(ClipType.ctDifference, P_nodeOutput.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
                    }
                }
            }



            // CELL
            // PROCESS CELL INPUT

            if (cellSrc_p != null)
            {
                if (P_Cell.polyTree != null)
                {
                    tmpPaths        = AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_Cell.polyTree));
                    doPolyTreeCells = true;
                    clipper         = new Clipper();
                }
                else
                {
                    tmpPaths           = P_Cell.getClonePaths();
                    P_cellOutput.paths = new Paths();
                }


                if (tmpPaths != null && tmpPaths.Count > 0)
                {
                    for (int i = 0; i < repeaterToolU.cells; i++)
                    {
                        for (int j = 0; j < repeaterToolV.cells; j++)
                        {
                            tm = localMatrixFromAddress(RepeaterItem.Cell, i, j);

                            if (doPolyTreeCells)
                            {
                                clipper.AddPaths(AX.Generators.Generator2D.transformPaths(tmpPaths, tm), PolyType.ptSubject, true);
                            }
                            else
                            {
                                Paths tmp = AX.Generators.Generator2D.transformPaths(tmpPaths, tm);
                                P_cellOutput.paths.AddRange(tmp);
                            }
                        }
                    }

                    if (doPolyTreeCells)
                    {
                        P_cellOutput.polyTree = new AXClipperLib.PolyTree();
                        clipper.Execute(ClipType.ctDifference, P_cellOutput.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
                    }
                }
            }

            /*
             * if ( P_Output.polyTree != null)
             * {
             *      transformPolyTree(P_Output.polyTree, localMatrix);
             * }
             * else if (P_Output.paths != null)
             * {
             *      P_Output.paths = transformPaths(P_Output.paths, localMatrix);
             *      P_Output.transformedControlPaths = P_Output.paths;
             * }
             */

            P_Output.polyTree = null;

            if (nodeSrc_p != null && cellSrc_p == null)
            {
                // JUST NODES
                AXShape.thickenAndOffset(ref P_Output, P_nodeOutput);
            }

            else if (nodeSrc_p == null && cellSrc_p != null)
            {
                // JUST CELLS
                AXShape.thickenAndOffset(ref P_Output, P_cellOutput);
            }
            else
            {
                // BOTH TO COMBINE
                clipper = new Clipper();

                if (P_nodeOutput.polyTree == null)
                {
                    clipper.AddPaths(P_nodeOutput.paths, PolyType.ptSubject, true);
                }
                else
                {
                    clipper.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_nodeOutput.polyTree)), PolyType.ptSubject, true);
                }

                if (P_cellOutput.polyTree == null)
                {
                    clipper.AddPaths(P_cellOutput.paths, PolyType.ptSubject, true);
                }
                else
                {
                    clipper.AddPaths(AXGeometryTools.Utilities.cleanPaths(Clipper.PolyTreeToPaths(P_cellOutput.polyTree)), PolyType.ptSubject, true);
                }


                P_Output.polyTree = new AXClipperLib.PolyTree();
                clipper.Execute(ClipType.ctUnion, P_Output.polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                AXShape.thickenAndOffset(ref P_Output, P_Output);
            }


            if (P_Output.polyTree != null)
            {
                transformPolyTree(P_Output.polyTree, localMatrix);
            }
            else if (P_nodeOutput.paths != null)
            {
                P_Output.paths = transformPaths(P_nodeOutput.paths, localMatrix);
                P_Output.transformedControlPaths = P_nodeOutput.paths;
            }
            else if (P_cellOutput.paths != null)
            {
                P_Output.paths = transformPaths(P_cellOutput.paths, localMatrix);
                P_Output.transformedControlPaths = P_cellOutput.paths;
            }
            //base.generate(false, initiator_po, isReplica);
            calculateBounds();

            return(null);
        }         // \generate
Esempio n. 13
0
        // SHAPE :: GENERATE
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica)
        {
            if (inputSrc_p == null)
            {
                return(null);
            }

            P_Input.polyTree = null;

            AXShape.thickenAndOffset(ref P_Input, inputSrc_p);


            P_Output.polyTree = null;
            AXShape.thickenAndOffset(ref P_Output, P_Input);


            // now take the output and segment it....

            Paths subjPaths = null;

            if (P_Output.polyTree != null)
            {
                subjPaths         = Clipper.PolyTreeToPaths(P_Output.polyTree);
                P_Output.polyTree = null;
            }
            else
            {
                subjPaths = P_Output.getPaths();
            }


            Path  src_path       = subjPaths[0];
            Paths segmentedPaths = new Paths();


            float y0     = 0;
            float height = parametricObject.floatValue("height");

            int segs = parametricObject.intValue("segments");

            float segHgt = height / segs;


            float zone_y;



            //
            int zoneCursor = 0;

            // begin the first zone path (or segment)
            Path zonePath = new Path();

            zonePath.Add(src_path[0]);

            // loop through segments in path
            for (int v = 0; v < (src_path.Count - 1); v++)
            {
                Debug.Log("v=" + v);
                IntPoint thisVert = src_path[v];
                IntPoint nextVert = src_path[v + 1];

                float slope = 0;

                if (nextVert.Y - thisVert.Y != 0)
                {
                    slope = (0.0f + (nextVert.X - thisVert.X)) / (0.0f + (nextVert.Y - thisVert.Y));
                }

                // do these y's cross over a segment line?
                for (int zone = zoneCursor; zone < segs; zone++)
                {
                    zone_y = (y0 + zone * segHgt) * AXGeometryTools.Utilities.IntPointPrecision;

                    Debug.Log("zone=" + zone + ", zone_y=" + zone_y + ",y0= " + y0 + ", segHgt=" + segHgt + ", segs=" + segs);

                    if (thisVert.Y < zone_y && nextVert.Y > zone_y)
                    {
                        // we have a crossover
                        float newX = (zone_y - thisVert.Y) * slope + thisVert.X;

                        // make a new point
                        IntPoint segPt = new IntPoint(newX, zone_y);


                        zonePath.Add(segPt);
                        segmentedPaths.Add(zonePath);

                        zonePath = new Path();
                        zonePath.Add(segPt);

                        //no need to look at zone less than this again
                    }
                }

                // Now add the upper vert...
                zonePath.Add(nextVert);
            }
            segmentedPaths.Add(zonePath);

            Debug.Log("segmentedPaths: " + segmentedPaths.Count);

            P_Output.paths = segmentedPaths;


            return(null);
        }
Esempio n. 14
0
        // GENERATE EXTRUDE
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter)
        {
            //Debug.Log ("===> [" + parametricObject.Name + "] EXTRUDE generate ... MAKE_GAME_OBJECTS="+makeGameObjects);

            if (parametricObject == null || !parametricObject.isActive)
            {
                return(null);
            }

            // RESULTING MESHES
            ax_meshes = new List <AXMesh>();


            //Debug.Log(" ******** A ");

            preGenerate();


            // PLAN -
            // The plan may have multiple paths. Each may generate a separate GO.
            if (P_Plan == null || planSrc_p == null || !planSrc_p.parametricObject.isActive)
            {
                return(null);
            }


            //Debug.Log(" ******** B " + planSrc_p.parametricObject.Name + "." + planSrc_p.Name);



            // Offset is bevel and !bevelOut
            float originalOffset = P_Plan.offset;

            // set back by the max bevel - later consider taper and lip....



            if (!bevelOut)
            {
                /*
                 * float bevelMax = (bevelTop > bevelBottom) ? bevelTop : bevelBottom;
                 *
                 * if (bevelMax > 0 )
                 * {
                 *      offsetModified -= bevelMax;
                 *      //P_Plan.joinType = JoinType.jtMiter;
                 * }
                 */

                P_Plan.offset -= (bevelBottom > bevelTop) ? bevelBottom : bevelTop;
            }



            // Splitting concave shapes?
            // THis is a pecial case. An ssumption is mad of no holes
            // so that we can deal only with paths.

            if (parametricObject.splitConcaveShapes)            //P_Plan.offset != 0)
            {
                // SPLIT INTO CONCAVES ** ** ** ** ** ** if no holes, and makeConcave,
                Paths       paths;
                AXParameter tmpSrc = (!renderToOutputParameter && P_Plan.Dependents != null) ? P_Plan : planSrc_p;

                if (tmpSrc.polyTree != null)
                {
                    paths = Clipper.PolyTreeToPaths(tmpSrc.polyTree);
                }
                else
                {
                    paths = tmpSrc.paths;
                }

                //Pather.printPaths(P_Plan.paths);

                if (paths != null)
                {
                    P_Plan.paths = new Paths();

                    foreach (Path path in paths)
                    {
                        Paths splitPaths = Pather.splitIntoConvexPaths(path);
                        splitPaths = Pather.offset(splitPaths, P_Plan.offset);
                        P_Plan.paths.AddRange(splitPaths);
                    }
                }
                P_Plan.polyTree = null;

                // SPLIT INTO CONCAVES ** ** ** ** ** ** ** ** if no holes, and makeConcave,
            }
            else
            {
                //Debug.Log("A: "+planSrc_p.paths[0].Count);
                P_Plan.polyTree = null;

                //			Debug.Log("EXTRUED " + parametricObject.Name);
                //			Pather.printPaths(P_Plan.paths);

                if (!renderToOutputParameter && P_Plan.Dependents != null)
                {
                    // Some Replicant has set the paths of this Plan_P manually
                    AXShape.thickenAndOffset(ref P_Plan, P_Plan);
                }
                else
                {
                    AXShape.thickenAndOffset(ref P_Plan, planSrc_p);
                }
            }

            P_Plan.offset = originalOffset;



            //Debug.Log("B: " +P_Plan.paths[0].Count);



            // DEFAULT SECTION -- USING BI_CHAMFER_SIDEflipX



            Path sectionPath = new Path();

            sectionPath = AXTurtle.BiChamferSide(extrude, bevelTop, bevelBottom, bevelSegs, true, taper, lipTop, lipBottom, lipEdge, lipEdgeBottom, segs);

            AXParameter sec_p = new AXParameter();

            sec_p.Parent           = parametricObject;
            sec_p.parametricObject = parametricObject;
            sec_p.Type             = AXParameter.DataType.Shape;
            sec_p.shapeState       = ShapeState.Open;
            sec_p.paths            = new Paths();
            sec_p.paths.Add(sectionPath);

            if (parametricObject.boolValue("Bevel Hard Edge"))
            {
                sec_p.breakGeom = 0;
                sec_p.breakNorm = 0;
            }



            //StopWatch sw = new StopWatch();
            //Debug.Log("Extrude ===================== ");
            GameObject retGO = generateFirstPass(initiator_po, makeGameObjects, P_Plan, sec_p, Matrix4x4.identity, renderToOutputParameter);

            //Debug.Log("Extrude Done ===================== " + sw.duration());


            // FINISH AX_MESHES

            parametricObject.finishMultiAXMeshAndOutput(ax_meshes, true);            //renderToOutputParameter);



            // FINISH BOUNDING

            setBoundaryFromAXMeshes(ax_meshes);

            //Debug.Log("Extrude: "+ parametricObject.bounds);

            return(retGO);
        }
Esempio n. 15
0
        public static void DrawOutputPaths(Texture2D canvas, AXParametricObject po, float texSize, float imageSize)
        {
            if (po == null)
            {
                return;
            }

            // GET OUTPUT PARAMETER
            AXParameter p = po.getPreferredOutputSplineParameter();

            if (p == null)
            {
                return;
            }

            bool isClosed = (p.shapeState == ShapeState.Closed);

            Paths paths = null;

            if (p.polyTree != null)
            {
                paths = Clipper.PolyTreeToPaths(p.polyTree);
            }
            else if (p.paths != null)
            {
                paths = p.paths;
            }



            Rect  bounds = AXGeometryTools.Utilities.getClipperBounds(paths);
            float maxdim = (bounds.width > bounds.height) ? bounds.width : bounds.height;
            float scale  = imageSize / maxdim;


            long[] shifter       = AXGeometryTools.Utilities.getShifterToPathsCenter(paths);
            Paths  centeredPaths = AXGeometryTools.Utilities.shiftPathsAsGroup(paths, shifter);



            //Archimatix.printPaths(centeredPaths);

            Vector2 offset = new Vector2(texSize / 2, texSize / 2);

            float rot = po.floatValue("Rot_Z");



            Color lineColor = Color.magenta;

            lineColor = new Color(1, .5f, 1);
            foreach (Path path in centeredPaths)
            {
                Library.DrawPathsOnTexture(canvas, AXGeometryTools.Utilities.path2Vec2s(path, rot, scale), offset, isClosed, lineColor);
            }

            // AXES
            long s = (shifter[2] / 18);

            Path xaxis = new Path();

            xaxis.Add(new IntPoint(-s - shifter[0], -shifter[1]));
            xaxis.Add(new IntPoint(s - shifter[0], -shifter[1]));
            Library.DrawPathsOnTexture(canvas, AXGeometryTools.Utilities.path2Vec2s(xaxis, rot, scale), offset, false, Color.white);

            Path yaxis = new Path();

            yaxis.Add(new IntPoint(-shifter[0], -s - shifter[1]));
            yaxis.Add(new IntPoint(-shifter[0], s - shifter[1]));
            Library.DrawPathsOnTexture(canvas, AXGeometryTools.Utilities.path2Vec2s(yaxis, rot, scale), offset, false, Color.white);
        }
Esempio n. 16
0
        // GENERATE WINWALL
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter)
        {
            if (parametricObject == null || !parametricObject.isActive)
            {
                return(null);
            }


            //Debug.Log("PlanSweep::generate()");

            // RESULTING MESHES
            ax_meshes = new List <AXMesh>();


            preGenerate();



            // PLAN
            // The plan may have multiple paths. Each may generate a separate GO.

            if (P_Plan == null)
            {
                return(null);
            }


            planSrc_p  = getUpstreamSourceParameter(P_Plan);
            planSrc_po = (planSrc_p != null)                                                           ? planSrc_p.parametricObject    : null;

            if (planSrc_p == null || !planSrc_p.parametricObject.isActive)
            {
                return(null);
            }


            planIsClosed = (P_Plan.hasThickness || P_Plan.shapeState == ShapeState.Closed) ? true : false;


            P_Plan.polyTree = null;

            Paths planPaths = planSrc_p.getPaths();

            Path planPath = planPaths[0];

            Spline planSpline = new Spline(planPath, planIsClosed, P_Plan.breakGeom, P_Plan.breakNorm);



            Paths offsetPaths = Pather.wallOffsets(planSpline, .5f, .5f);

            Pather.printPaths(offsetPaths);


            // each path, step through and mak a rectangle
            // segment wide and height and then subtract windows.

            //Then make poly and add to combiner

            Path window = AXTurtle.Rectangle(1, 1, false);

            //window.Reverse();
            Pather.shiftPath(window, new IntPoint(10000, 5000));

            Debug.Log("==========");
            Pather.printPath(window);



            Pather rightPather = new Pather(offsetPaths[0]);

            int[] rightLengths = rightPather.segment_lengths;

            for (int i = 0; i < rightLengths.Length; i++)
            {
                Debug.Log(rightLengths[i]);

                int next_i = (i == rightLengths.Length - 1) ? 0 : i + 1;

                Path rect = AXTurtle.Rectangle(rightLengths[next_i] / 10000f, 3, false);



                Clipper c = new Clipper();
                c.AddPath(rect, PolyType.ptSubject, true);

                // fenestration
                c.AddPath(window, PolyType.ptClip, true);

                AXClipperLib.PolyTree polytree = new AXClipperLib.PolyTree();
                c.Execute(ClipType.ctDifference, polytree, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                Paths pathResult = Clipper.PolyTreeToPaths(polytree);


                Pather.printPaths(pathResult);

                Mesh mesh = AXPolygon.triangulate(polytree, new AXTexCoords());


                Matrix4x4 wallm = Matrix4x4.TRS(new Vector3(offsetPaths[0][i].X / 10000f, 0, offsetPaths[0][i].Y / 10000f), Quaternion.Euler(-90, planSpline.edgeRotations[i], 0), Vector3.one);

                ax_meshes.Add(new AXMesh(mesh, wallm));
            }

            parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter);


            // FINISH BOUNDING

            setBoundaryFromAXMeshes(ax_meshes);


            if (makeGameObjects)
            {
                return(parametricObject.makeGameObjectsFromAXMeshes(ax_meshes));
            }


            return(null);
        }