Author Topic: 3DFACE IntersectWith method  (Read 12542 times)

0 Members and 1 Guest are viewing this topic.

Odoshi

  • Guest
3DFACE IntersectWith method
« on: January 26, 2011, 09:13:31 AM »
Hey everyone,

First post here and I'm hoping it's an easy one.

I have 2 Face objects I am trying to Intersect.

a) I would like to know if IntersectWith() will return points where one face cuts through another, or does it just give intersection points where their "frames" intersect, for example, if they were edge to edge.

In my case, picture a small window pane cutting through a larger window pane, perpendicularly. Their frames do not intersect, but the glass does.

b) Do they have to be added to the DB, or can I create them in memory and run IntersectWith()?

Regards,
Mike

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #1 on: January 26, 2011, 10:50:45 AM »
Hi Mike,

Welcome to theswamp.

You, can include also an image or drawing sample, to have a better idea of the problem.



Luis.

Odoshi

  • Guest
Re: 3DFACE IntersectWith method
« Reply #2 on: January 26, 2011, 11:41:30 AM »
OK, sure thing. Here the yellow faces are cut by the red triangle faces.

Thanks,
Mike

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #3 on: January 26, 2011, 01:01:52 PM »
Did you tried?

I do not see a direct way to get the intersection using this method.

GetPlane(); do not work either...

Maybe by extracting the vertex and created the plane apart... have not tried that.

SOFITO_SOFT

  • Guest
Re: 3DFACE IntersectWith method
« Reply #4 on: January 26, 2011, 02:02:35 PM »
Hello:
¿ Is it to do something like the picture?

¿ with horizontal cuts or any angle?

Greetings.
 

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #5 on: January 26, 2011, 02:50:07 PM »
Here it is the way I was able to get the intersection (objects that can be used to build a points collection if required), it is based on 3d faces made of 4 points, see if helps (a quick one no error control, etc...):
Luis.
Code: [Select]
       [CommandMethod("INTF", CommandFlags.Modal)]
        public void cmd_intersFaces()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            PromptEntityOptions peo = new PromptEntityOptions("");
            peo.Message = "\n<Enter to exit>/Select first 3d face";
            peo.SetRejectMessage("\n***Object must be a 3d face. \n");
            peo.AddAllowedClass(typeof(Face), true);
            peo.AllowNone = true;
            PromptEntityResult per1 = ed.GetEntity(peo);
            if (per1.Status != PromptStatus.OK) return;

            peo.Message = "\n<Enter to exit>/Select second 3d face";
            PromptEntityResult per2 = ed.GetEntity(peo);
            if (per2.Status != PromptStatus.OK) return;

            //Point3dCollection ints = new Point3dCollection();

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false) as BlockTableRecord;
                Face face1 = tr.GetObject(per1.ObjectId, OpenMode.ForWrite, false) as Face;
                Face face2 = tr.GetObject(per2.ObjectId, OpenMode.ForWrite, false) as Face;
                
                DBObjectCollection curveSegments = new DBObjectCollection();
                DBObjectCollection regions = new DBObjectCollection();

                Point3d p1, p2, p3, p4;
                Line line = null;

                p1 = face1.GetVertexAt(0);
                p2 = face1.GetVertexAt(1);
                p3 = face1.GetVertexAt(2);
                p4 = face1.GetVertexAt(3);

                line = new Line(p1, p2);
                curveSegments.Add(line);
                line = new Line(p2, p3);
                curveSegments.Add(line);
                line = new Line(p3, p4);
                curveSegments.Add(line);
                line = new Line(p4, p1);
                curveSegments.Add(line);

                regions = Region.CreateFromCurves(curveSegments);
                Region region1 = (Region)regions[0];

                p1 = face2.GetVertexAt(0);
                p2 = face2.GetVertexAt(1);
                p3 = face2.GetVertexAt(2);
                p4 = face2.GetVertexAt(3);

                curveSegments.Clear();
                regions.Clear();

                line = new Line(p1, p2);
                curveSegments.Add(line);
                line = new Line(p2, p3);
                curveSegments.Add(line);
                line = new Line(p3, p4);
                curveSegments.Add(line);
                line = new Line(p4, p1);
                curveSegments.Add(line);

                regions = Region.CreateFromCurves(curveSegments);
                Region region2 = (Region)regions[0];
                
                PlaneSurface psurface1 = new PlaneSurface();
                psurface1.CreateFromRegion(region1);

                PlaneSurface psurface2 = new PlaneSurface();
                psurface2.CreateFromRegion(region2);

                Entity[] entities = psurface1.BooleanIntersect(psurface2);
                foreach (Entity e in entities)
                {
                    // convert to curve objects
                    // or
                    // convert entities into lines or arcs
                    // or
                    // join them into a single object polyline
                    // or
                    // extract the points
                    // or
                    // append the object into the drawing if needed
                    //btr.AppendEntity(e);
                    //tr.AddNewlyCreatedDBObject(e, true);
                }

                tr.Commit();
            }
        }

Odoshi

  • Guest
Re: 3DFACE IntersectWith method
« Reply #6 on: January 26, 2011, 05:11:53 PM »
Yes, I wish to "slice" the faces. I take it, it's possible, before adding them to the DB? Would you have a snippet?

Thanks!
Mike


Hello:
¿ Is it to do something like the picture?

 

Odoshi

  • Guest
Re: 3DFACE IntersectWith method
« Reply #7 on: January 26, 2011, 05:15:17 PM »
Yea, that looks like a long way around it. I was hoping to use:

Faces.IntersectWith(fss, Intersect.OnBothOperands, pnts, imk1, imk1);

But maybe I'm not sure of its uses.

Mike


Here it is the way I was able to get the intersection (objects that can be used to build a points collection if required), it is based on 3d faces made of 4 points, see if helps (a quick one no error control, etc...):
Luis.


LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #8 on: January 26, 2011, 05:32:19 PM »
Yes,
But it does not work (at least in all my tests here) with Face objects :).

Yea, that looks like a long way around it. I was hoping to use:

Faces.IntersectWith(fss, Intersect.OnBothOperands, pnts, imk1, imk1);

But maybe I'm not sure of its uses.

Mike


Here it is the way I was able to get the intersection (objects that can be used to build a points collection if required), it is based on 3d faces made of 4 points, see if helps (a quick one no error control, etc...):
Luis.


LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #9 on: January 26, 2011, 07:12:25 PM »
OK... did a little more testings... and it works the IntersectWith with the 3d faces (Face) but only when the face segments are touching each other, have a look into the image:

Code: [Select]
                //face1.IntersectWith(face2, Intersect.OnBothOperands, projectionPlane, points, 0, 0);
                //face1.IntersectWith(face2, Intersect.OnBothOperands, points, 0, 0);
                face1.IntersectWith(face2, Intersect.ExtendBoth, points, 0, 0);

                ed.WriteMessage("\nPoints count: {0} \n", points.Count.ToString());

                foreach (Point3d pt in points)
                {
                    DBPoint point = new DBPoint();
                    point.Position = pt;
                    btr.AppendEntity(point);
                    tr.AddNewlyCreatedDBObject(point, true);
                }
 

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #10 on: January 26, 2011, 08:07:10 PM »
So, got the chance to play a little more and looks like the ticket it is the use of a projection plane, did more tests here and works.
Code: [Select]

                Plane projectionPlane = new Plane();
                Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
                CoordinateSystem3d ucs = new CoordinateSystem3d();
                ucs = ucsMatrix.CoordinateSystem3d;
                //projectionPlane = new Plane(ucs.Origin, ucs.Xaxis, ucs.Yaxis);
                //face1.IntersectWith(face2, Intersect.ExtendBoth, projectionPlane, points, 0, 0);

                projectionPlane = new Plane(face2.GetVertexAt(0), ucs.Xaxis, ucs.Yaxis);
                face1.IntersectWith(face2, Intersect.ExtendThis, projectionPlane, points, 0, 0);
HTH.
« Last Edit: January 26, 2011, 08:12:42 PM by LE »

SOFITO_SOFT

  • Guest
Re: 3DFACE IntersectWith method
« Reply #11 on: January 27, 2011, 08:06:00 AM »
Code: [Select]
(DEFUN INTER_3DCARA_PLANO (ENT     A      B       C        D      /
    LISTA-INTER      N        LISTA-LINEA     TRIAN    INT1
  )
  (SETQ LISTA-LINEA '())
  (SETQ TRIAN (MEJOR_TRIAN_3DCARA ENT))   [color=red];<<<<SEPARATE THE 3DFACE IN 2 TRIANGLES if exist 2 (only 1 is psibble). [/color]
  (FOREACH N TRIAN
    (SETQ LISTA-INTER '())
    (IF (AND
  (SETQ INT1
(INTER_PLANO_GENER_VECTO_2P A B C D (NTH 0 N) (NTH 1 N))    ;[color=red]<<< INTERSECTION CUT PLANE ( BY A B C D =  GERENAL ECUACION FORM OF PLANE X 3 POINTS OF CUT PLANE) WITH EACH EDGE OF 3DFACE[/color]
  )
  (SETQ INT1 (CAR INT1))
  (NOT (member-equal INT1 LISTA-INTER TOLER-IGUAL))            [color=red] ;<<<< TOLER-IGUAL = 1E-8 [/color]
  (AND (ESTA_PUNTO_ENTRE_2PUNTOS                                    [color=red] ; <<<<PTO INTERS. IS BETWEEN  EXTREMES EDGE 3DFACE[/color]
INT1
(NTH 0 N)
(NTH 1 N)
TOLER-IGUAL
       )
  )
)
      (PROGN
(SETQ LISTA-INTER (APPEND LISTA-INTER (LIST INT1)))
      )
    )
    (IF (AND
  (SETQ INT1
(INTER_PLANO_GENER_VECTO_2P A B C D (NTH 1 N) (NTH 2 N))    [color=red]; <<< FOR EACH couple extremes  EDGES 3DFACE[/color]
  )
  (SETQ INT1 (CAR INT1))
  (NOT (member-equal INT1 LISTA-INTER TOLER-IGUAL))
  (AND (ESTA_PUNTO_ENTRE_2PUNTOS
INT1
(NTH 1 N)
(NTH 2 N)
TOLER-IGUAL
       )
  )
)
      (PROGN
(SETQ LISTA-INTER (APPEND LISTA-INTER (LIST INT1)))
      )
    )
    (IF (AND
  (SETQ INT1
(INTER_PLANO_GENER_VECTO_2P A B C D (NTH 2 N) (NTH 0 N))
  )
  (SETQ INT1 (CAR INT1))
  (NOT (member-equal INT1 LISTA-INTER TOLER-IGUAL))
  (AND (ESTA_PUNTO_ENTRE_2PUNTOS
INT1
(NTH 2 N)
(NTH 0 N)
TOLER-IGUAL
       )
  )
)
      (PROGN
(SETQ LISTA-INTER (APPEND LISTA-INTER (LIST INT1)))
      )
    )
    (IF (= 2 (LENGTH LISTA-INTER))                    [color=red];<<<< ONLY IF 2 INTERSECTIONS EXIST, IS OK[/color]
      (PROGN
;;; (COMMAND "LINE" (NTH 0 LISTA-INTER) (NTH 1 LISTA-INTER) "")   ;<<<< for verify during tests
(SETQ LISTA-LINEA (APPEND LISTA-LINEA (LIST (ENTLAST))))
      )
    )
  ) ; FOREACH
  LISTA-LINEA
)
I only know a little Alisp language , but I copied the program I use. I put comments in red, for you to do the algorithm.
The method is not sophisticated but it works. The dog was cut sliced so. The advantage is that you can tell the 3DFACE any angle.
Just changing the A B C D (the general equation), which is easier to get 3 points of the cutting plane.
I hope to help you.
Regards from Madrid.

Odoshi

  • Guest
Re: 3DFACE IntersectWith method
« Reply #12 on: January 27, 2011, 09:43:10 AM »
Yes, that's the ticket. Thanks for your help!

Mike


So, got the chance to play a little more and looks like the ticket it is the use of a projection plane, did more tests here and works.
Code: [Select]

                Plane projectionPlane = new Plane();
                Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
                CoordinateSystem3d ucs = new CoordinateSystem3d();
                ucs = ucsMatrix.CoordinateSystem3d;
                //projectionPlane = new Plane(ucs.Origin, ucs.Xaxis, ucs.Yaxis);
                //face1.IntersectWith(face2, Intersect.ExtendBoth, projectionPlane, points, 0, 0);

                projectionPlane = new Plane(face2.GetVertexAt(0), ucs.Xaxis, ucs.Yaxis);
                face1.IntersectWith(face2, Intersect.ExtendThis, projectionPlane, points, 0, 0);
HTH.

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #13 on: January 27, 2011, 11:08:04 AM »
Good, I have used a lot the intersectWith method in arx, c# and in my vlisp days, but zero about the usage of a plane as argument, nor with 3d faces... so got the chance to learn too. :)

Cheers,
Luis.

Yes, that's the ticket. Thanks for your help!

Swift

  • Swamp Rat
  • Posts: 596
Re: 3DFACE IntersectWith method
« Reply #14 on: January 27, 2011, 11:09:57 AM »
That's some good work Luis!

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #15 on: January 27, 2011, 11:19:07 AM »
Very mickey mouse help but glad that helps :)
Thanks Swift!

That's some good work Luis!

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #16 on: January 27, 2011, 11:29:52 AM »
Hola Sofito_Soft,
Interesante lo que muestras en las imagenes que subiste, y que lo haces mediante autolisp, muy bien!

Nice, stuff you did and more when can be done via lisp, good!

Saludos.
Luis.



Code: [Select]
(DEFUN INTER_3DCARA_PLANO (ENT     A      B       C        D      /
    LISTA-INTER      N        LISTA-LINEA     TRIAN    INT1
       TOLER-IGUAL
I hope to help you.
Regards from Madrid.

Odoshi

  • Guest
Re: 3DFACE IntersectWith method
« Reply #17 on: January 27, 2011, 03:27:53 PM »
Actually, I am still not getting the desired results.

In your picture, which color is face1 and face2? Then I will know which is extended.

Thanks,
Mike

Good, I have used a lot the intersectWith method in arx, c# and in my vlisp days, but zero about the usage of a plane as argument, nor with 3d faces... so got the chance to learn too. :)

Cheers,
Luis.

Yes, that's the ticket. Thanks for your help!

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #18 on: January 27, 2011, 03:52:02 PM »
Here it goes my code and an animated image - yellow 3d face first - red in second:
Code: [Select]
[CommandMethod("INTF", CommandFlags.Modal)]
public void cmd_intersFaces()
{
    Document doc = AcadApp.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;
    Database db = doc.Database;

    PromptEntityOptions peo = new PromptEntityOptions("");
    peo.Message = "\n<Enter to exit>/Select first 3d face (to project)";
    peo.SetRejectMessage("\n***Object must be a 3d face. \n");
    peo.AddAllowedClass(typeof(Face), true);
    peo.AllowNone = true;
    PromptEntityResult per1 = ed.GetEntity(peo);
    if (per1.Status != PromptStatus.OK) return;

    peo.Message = "\n<Enter to exit>/Select second 3d face (projection plane)";
    PromptEntityResult per2 = ed.GetEntity(peo);
    if (per2.Status != PromptStatus.OK) return;

    Point3dCollection points = new Point3dCollection();

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false) as BlockTableRecord;

        Face face1 = tr.GetObject(per1.ObjectId, OpenMode.ForWrite, false) as Face;
        Face face2 = tr.GetObject(per2.ObjectId, OpenMode.ForWrite, false) as Face;

        Plane projectionPlane = new Plane();
        Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
        CoordinateSystem3d ucs = new CoordinateSystem3d();
        ucs = ucsMatrix.CoordinateSystem3d;

        projectionPlane = new Plane(face2.GetVertexAt(0), ucs.Xaxis, ucs.Yaxis);
        face1.IntersectWith(face2, Intersect.OnBothOperands, projectionPlane, points, 0, 0);

        #region debug print message and points
        ed.WriteMessage("\nPoints count: {0} \n", points.Count.ToString());
        foreach (Point3d pt in points)
        {
            DBPoint point = new DBPoint();
            point.Position = pt;
            btr.AppendEntity(point);
            tr.AddNewlyCreatedDBObject(point, true);
        }
        #endregion

        tr.Commit();
    }
}
« Last Edit: January 27, 2011, 05:49:13 PM by LE »

LE3

  • Guest
Re: 3DFACE IntersectWith method
« Reply #19 on: January 27, 2011, 05:54:14 PM »
Ok... I did some corrections, this one works on all the cases.

INTF = if does not find the intersection, select the faces in inverse sequence.
INTF2 = works in all cases.

Let me know if works for you.

edit: removed extraction of vertex 4 not required.
Code: [Select]
[CommandMethod("INTF", CommandFlags.Modal)]
public void cmd_intersFaces()
{
    Document doc = AcadApp.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;
    Database db = doc.Database;

    PromptEntityOptions peo = new PromptEntityOptions("");
    peo.Message = "\n<Enter to exit>/Select first 3d face (to project)";
    peo.SetRejectMessage("\n***Object must be a 3d face. \n");
    peo.AddAllowedClass(typeof(Face), true);
    peo.AllowNone = true;
    PromptEntityResult per1 = ed.GetEntity(peo);
    if (per1.Status != PromptStatus.OK) return;

    peo.Message = "\n<Enter to exit>/Select second 3d face (projection plane)";
    PromptEntityResult per2 = ed.GetEntity(peo);
    if (per2.Status != PromptStatus.OK) return;

    Point3dCollection points = new Point3dCollection();

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false) as BlockTableRecord;

        Face faceProject = tr.GetObject(per1.ObjectId, OpenMode.ForWrite, false) as Face;
        Face facePlane = tr.GetObject(per2.ObjectId, OpenMode.ForWrite, false) as Face;

        Point3d p1, p2, p3;
        p1 = facePlane.GetVertexAt(0);
        p2 = facePlane.GetVertexAt(1);
        p3 = facePlane.GetVertexAt(2);
        Vector3d vU = p2.GetAsVector() - p1.GetAsVector();
        Vector3d vV = p3.GetAsVector() - p1.GetAsVector();
        Plane projectionPlane = new Plane(p1, vU, vV);

        facePlane.IntersectWith(faceProject, Intersect.ExtendArgument, projectionPlane, points, 0, 0);

        #region debug print message and points
        ed.WriteMessage("\nPoints count: {0} \n", points.Count.ToString());
        foreach (Point3d pt in points)
        {
            DBPoint point = new DBPoint();
            point.Position = pt;
            btr.AppendEntity(point);
            tr.AddNewlyCreatedDBObject(point, true);
        }
        #endregion

        tr.Commit();
    }
}

[CommandMethod("INTF2", CommandFlags.Modal)]
public void cmd_intersFaces2()
{
    Document doc = AcadApp.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;
    Database db = doc.Database;

    PromptEntityOptions peo = new PromptEntityOptions("");
    peo.Message = "\n<Enter to exit>/Select first 3d face (to project)";
    peo.SetRejectMessage("\n***Object must be a 3d face. \n");
    peo.AddAllowedClass(typeof(Face), true);
    peo.AllowNone = true;
    PromptEntityResult per1 = ed.GetEntity(peo);
    if (per1.Status != PromptStatus.OK) return;

    peo.Message = "\n<Enter to exit>/Select second 3d face (projection plane)";
    PromptEntityResult per2 = ed.GetEntity(peo);
    if (per2.Status != PromptStatus.OK) return;

    Point3dCollection points = new Point3dCollection();

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false) as BlockTableRecord;

        Face faceProject = tr.GetObject(per1.ObjectId, OpenMode.ForWrite, false) as Face;
        Face facePlane = tr.GetObject(per2.ObjectId, OpenMode.ForWrite, false) as Face;

        Point3d p1, p2, p3;
        p1 = facePlane.GetVertexAt(0);
        p2 = facePlane.GetVertexAt(1);
        p3 = facePlane.GetVertexAt(2);
        Vector3d vU = p2.GetAsVector() - p1.GetAsVector();
        Vector3d vV = p3.GetAsVector() - p1.GetAsVector();
        Plane projectionPlane = new Plane(p1, vU, vV);

        facePlane.IntersectWith(faceProject, Intersect.ExtendArgument, projectionPlane, points, 0, 0);

        if (points.Count == 0)
        {
            p1 = faceProject.GetVertexAt(0);
            p2 = faceProject.GetVertexAt(1);
            p3 = faceProject.GetVertexAt(2);            
            vU = p2.GetAsVector() - p1.GetAsVector();
            vV = p3.GetAsVector() - p1.GetAsVector();
            projectionPlane = new Plane(p1, vU, vV);
            faceProject.IntersectWith(facePlane, Intersect.ExtendArgument, projectionPlane, points, 0, 0);
        }

        #region debug print message and points
        ed.WriteMessage("\nPoints count: {0} \n", points.Count.ToString());
        foreach (Point3d pt in points)
        {
            DBPoint point = new DBPoint();
            point.Position = pt;
            btr.AppendEntity(point);
            tr.AddNewlyCreatedDBObject(point, true);
        }
        #endregion

        tr.Commit();
    }
}
« Last Edit: January 29, 2011, 12:25:45 AM by LE »

Odoshi

  • Guest
Re: 3DFACE IntersectWith method
« Reply #20 on: February 01, 2011, 05:55:11 AM »
I've got it working now. My faces had 3 visible points, not 4, and calc'ing the normal is a little different. Also, since my intersecting planes were always with a Z-axis normal, I was able to figure out the projection plane.

Thanks for all your help,
Mike