use editor methods while jigging?

use editor methods while jigging?

a.kouchakzadeh
Advocate Advocate
657 Views
9 Replies
Message 1 of 10

use editor methods while jigging?

a.kouchakzadeh
Advocate
Advocate

Hello every one.
Im trying to combine Jig with editor methods but it seems not to work.
I have a jig class which is jigging a block reference and a polyline at the same time... I want to constantly check if a certain block reference and certain entities are inside the polyline passed to this Jig class in the sampler status method of Jig.
to check if a block is inside a polyline or not, this post from @_gile is handy.

but It seems since I have already called ed.drag(jig), editor methods wont work anymore?

0 Likes
Accepted solutions (1)
658 Views
9 Replies
Replies (9)
Message 2 of 10

norman.yuan
Mentor
Mentor

You may want to provide some explanations of what are "editor methods" you refer to, and why it has anything to do with user running your Jig.

 

If "editor methods" mean the set of methods of Editor.GetXxxxx(), then, there is no reason to use them, because a Jig is basically a super version of a Editor.GetXxxxx(), depending on which JigPrompt.AcquireXxxxx() method you call in the Sampler() overridden methods.

 

So, please describe your question as how you want to user to do when running the jig.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 10

ActivistInvestor
Mentor
Mentor

You don't mention what editor method you are trying to use from the jigs sampler function, but I'm guessing that it is a selection method to select all objects inside of the polyline. I very much doubt that it's going to work within a call to the Drag() method, and if that is the case the solution to your problem is non-trivial.

 

The way I would approach it is to gather all of the eligible objects that are visible on the display before you call drag and use spatial indexing (e.g. quad tree) to quickly identify any objects whose  bounding box is contained within or intersects the bounding box of the polyline that you are dragging.

0 Likes
Message 4 of 10

a.kouchakzadeh
Advocate
Advocate

Hi Mr. Yuan
as you guessed, Im looking for an editor.selection() method. to be more specific, Im jigging a polyline along a blockreference and Im willing to gather special block references and lines and line segments in that polyline (my initial guess was to use ed.SelectFence(polyline verticies).
Im trying to make my code run so I can post the chunck Im having this question on, but im facing many parts that I have to fix before posting so its taking me a while.
but I think you got my point.
by the way, Im also using jpo.AcquirePoint(jigOpts) to get the point I need.

0 Likes
Message 5 of 10

a.kouchakzadeh
Advocate
Advocate

@ActivistInvestor, thanks for the reply, I took a look at the link but could you please give me a little more details about spatial indexing?

0 Likes
Message 6 of 10

ActivistInvestor
Mentor
Mentor

Sorry I don't really have the time to write the code. Have a look at this which uses the code found here

0 Likes
Message 7 of 10

norman.yuan
Mentor
Mentor

It is still not clear to me that what exactly your intention is. You might want to describe it in more details, and/or with a picture showing what is dragged and what are needed to know while user drags.

Here is my assumption: say, the jig lets user drag a closed polyline, while dragging, the user wants to know what entities are within the boundary of the dragged polygon, or know if particular entities are inside the dragged polygon. If that is the case, you need to do the calculation to determine whether some entities are inside the dynamic moving boundary, when found, you could somehow visually highlight them (either call Entity.Highlight() or draw Transient graphics). As a CAD programmer, one should be able to computer to determine whether some entities are inside a boundary, other than calling Editor.SelectCrosding[Window/Fence](). IN the case of boundary being a moving, as jigged polyline, you just need to do the calculation either in the overridden Sampler() or Update()/WorldDraw().

Again, not sure what exactly you want to do, this only a shoot in the dark.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 8 of 10

a.kouchakzadeh
Advocate
Advocate

This is what Im trying to achieve sir:

 

protected override SamplerStatus Sampler(JigPrompts prompts)
{
    _dwg.Database.Orthomode = true;

    var jigOptions = new JigPromptPointOptions();

    jigOptions.SetMessageAndKeywords("\nInsert Sprinkler or [Rotate]:", "Rotate");

    var jigResult = prompts.AcquirePoint(jigOptions);

    switch (jigResult.Status)
    {
        case PromptStatus.Keyword:

            //Rotate blkRef and region
            break;

        case PromptStatus.OK:
            switch (_movingPoint.Equals(jigResult.Value))
            {
                case true:
                    return SamplerStatus.NoChange;
                case false:

                    var reflectedPoint = _wallsAndSoffits.BaseLine.GetClosestPointTo(
                        jigResult.Value, false);

                    _sideWallBlkReference.Position = reflectedPoint;

                    var movingVecotr = _movingPoint.GetVectorTo(reflectedPoint);
                    _pcaRegion.TransformBy(Matrix3d.Displacement(movingVecotr));
                    _pcaPolyline.TransformBy(Matrix3d.Displacement(movingVecotr));
                    _movingPoint = reflectedPoint;

                    //my question is here:
                    var objectsIndisde = ed.SelectFence(_pcaPolyline.GetVertexAsPointCol(),sFilter);
                    foreach(SelectedObject selected in objectsIndisde.Value.GetObjectIds())
                    {
                        if(selected is Line)
                        {
                            //check distance of _moving point to line, if less than xxx do stuff
                        }
                        else if(selected is BlockReference)
                        {
                            //check distance of _moving point and selected, if less than xxx insert aligned dimension
                        }
                        else if(selected is polylinesegment)
                        {
                            //do some stuff to the region
                        }
                    }
                    return SamplerStatus.OK;
            }
            break;

        default:
            return SamplerStatus.Cancel;
    }

    return SamplerStatus.NoChange;
}

 

I tried to simplify my code as much as possible,
this is an image to describe the problem:

akouchakzadeh_1-1700220645986.png

 

 

 

 

0 Likes
Message 9 of 10

norman.yuan
Mentor
Mentor
Accepted solution

So, the issue you have is quite simple: as CAD programmer, write your own code that is equivalent to the Editor.SelectFence() or SelectCrossingPolygon[Window]() (in your case, it should be the latter). Something like:

 

 

protected override SamplerStatus Sampler(JigPrompts prompts)
{
    _dwg.Database.Orthomode = true;

    var jigOptions = new JigPromptPointOptions();

    jigOptions.SetMessageAndKeywords("\nInsert Sprinkler or [Rotate]:", "Rotate");

    var jigResult = prompts.AcquirePoint(jigOptions);
    switch (jigResult.Status)
    {
        case PromptStatus.Keyword:

            //Rotate blkRef and region
            break;

        case PromptStatus.OK:
            switch (_movingPoint.Equals(jigResult.Value))
            {
                case true:
                    return SamplerStatus.NoChange;
                case false:

                    var reflectedPoint = _wallsAndSoffits.BaseLine.GetClosestPointTo(
                        jigResult.Value, false);

                    _sideWallBlkReference.Position = reflectedPoint;

                    var movingVecotr = _movingPoint.GetVectorTo(reflectedPoint);
                    _pcaRegion.TransformBy(Matrix3d.Displacement(movingVecotr));
                    _pcaPolyline.TransformBy(Matrix3d.Displacement(movingVecotr));
                    _movingPoint = reflectedPoint;

                    // assume you have a Transaction started when the dragging begins
                    var objectsIndisde = SelectCrossingPolygon(_pcaPolyline)
                    foreach(Entity ent in objectsInside)
                    {
                        if(selected is Line)
                        {
                            //check distance of _moving point to line, if less than xxx do stuff
                        }
                        else if(selected is BlockReference)
                        {
                            //check distance of _moving point and selected, if less than xxx insert aligned dimension
                        }
                        else if(selected is polylinesegment)
                        {
                            //do some stuff to the region
                        }
                    }
                    return SamplerStatus.OK;
            }
            break;

        default:
            return SamplerStatus.Cancel;
    }

    return SamplerStatus.NoChange;
}

private List<Entity> SelectCrossingPolygon(Polyline boundary)
{
   var ents=new List<Entity>();
   var space=(BlockTableRecord)_tran.GetObject(_db.CurrentSpaceId, OpenMode.ForRead);
   foreach (ObjectId entId in space)
   {
   var ent=(Entity)_tran.GetObject(entId, OpenMode.ForRead);
     if (IsInsideOrCrossing(ent, boundary)) ents.Add(ents);
   }
   return ents;
}

private bool IsInsideOrCrossing(Entity ent, Polyline boundary)
{
  // first test if there is intersection
  var pts=new Point3dCollection
  boundary.IntersectWith(ent, Intersect.OnBothOperants, pts, IntPtr.Zero, IntPtr.Zero);
  if (pts.Count>0) return true
  
  // if no intersection, get a point coordinate of anywhere of the entity:
  // if it is curve (line, Arc, polyline...), use Start/End point; if it is 
  // block reference, use Insertion Point...
  Point3d ptOnEntity = //get a point from the entity
  return IsPointInsideBoundary(ptOnEntity, boundary);
}

private bool IsPointInsideBoundary(Point3d pt, Polyline boundary)
{
  // There are quite a few code samples to compute whether a points
  // is inside a polygon online. Do your search
}

 

 

HTH

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 10 of 10

a.kouchakzadeh
Advocate
Advocate

that was a nice workaround! thanks Mr. Yuan

 

what if the objects in model space are too many? wont this method slow down the process? specially that the polyline is pretty small compared to the whole model space block table record?

0 Likes