Jump to content

Layer split in several layers


luiscarneirorm

Recommended Posts

Hi.

 

I am trying to develop an application to simplify my work, and I need to do the following:

I need to divide the elements found in a particular layer (base), for various layers (base1, base2 ...), each layer can have only objects within a given area.

 

two drawings below show, the first is the original, the second is what I intend to get.

ex1.dxf

ex2.dxf

 

in this example I have divided the drawing with a reference area of 200 * 200, but this value is supposed to be variable ...

if there is any object that does not fit in the area of reference it should be changed to the layer base_too_large

 

I have in my head about the idea of ​​how I do it, but transpose it to the lisp is that it is more complicated ...

 

Excuse the English (google translate:oops:)

Link to comment
Share on other sites

  • Replies 44
  • Created
  • Last Reply

Top Posters In This Topic

  • luiscarneirorm

    23

  • pBe

    20

  • BIGAL

    1

  • Jeff H

    1

Top Posters In This Topic

Posted Images

Sample

 

(defun c:test ()
     (vl-load-com)
     (if (not BArea)(setq BArea 100.00))
     (setq BArea (cond
                      ((getreal
                             (strcat "\nEnter Base Area:  <"
                                     (rtos BArea 2 2)
                                     ">: ")))
                      (BArea)))
       (setq LayerBase (getstring "\nEnter Layer Name: "))
     (setq objs (ssget '((0 . "LWPOLYLINE,CIRCLE,HATCH"))))
      (repeat (sslength objs)
       (if 
       (> (vla-get-area (vlax-ename->vla-object  (setq ent  (ssname objs 0)))) BArea)
               (entmod (subst (cons 8 LayerBase) (assoc 8 (setq ent (entget ent))) ent))
               )
      (ssdel (ssname objs 0) objs)
             )
     )

 

Problems i see with this approach is if you want to split them based on their areas in one go, you need to pass two values as arguments each time you run the code. a MAX and a MIN (fuzz) probably using a list and also mind the sequence.

 

Otherwise run the routine starting with small areas first then big ones.

Edited by pBe
Link to comment
Share on other sites

I think not myself clear,

What I mean is:

 

I have all the entities in a layer (base), then beginning to scan the layer from the bottom left corner.

when you find the first entity, create a window of 200 * 200 for example, and all entities that are completely within this window are sent to a new layer (base_1), then keep doing this scan and find another entity then again the previous step. is what I intend to keep the layers separate entities in the area with maximum of 200 * 200, and leave only the original layer entities that do not fit this area.

 

sorry if I am doing to understand:oops:

Link to comment
Share on other sites

I think not myself clear,

What I mean is:

 

I have all the entities in a layer (base), then beginning to scan the layer from the bottom left corner.

when you find the first entity, create a window of 200 * 200 for example, and all entities that are completely within this window are sent to a new layer (base_1), then keep doing this scan and find another entity then again the previous step. is what I intend to keep the layers separate entities in the area with maximum of 200 * 200, and leave only the original layer entities that do not fit this area.

 

 

Now I think i understand what you want to do.

 

So youre saying entities inside a 200x2000 window will be one layer? then do the same for the next window of the same size to another layer. and other entites outside of those boundaries will be named base_too_large

 

Starting from an user input point as the lower left corner. bottom row first left to right, then the next row on top of that left to right?

 

and. YES, someone here can and will help you :)

 

EDIT: the windows size, is it always a square?

Link to comment
Share on other sites

Here's a draft:

(defun c:test (/ sp osp cmt Boxobj lyn lnm lylst)
[color=olive] (setq sp '(0.0 0.0))[/color]
 (setq osp sp
[color=olive] wp  sp[/color]
cnt 1
 )
[color=blue] (if (not WdwSize)[/color]
[color=blue]           (setq WdwSize 200.00))[/color]
[color=blue]     (setq WdwSize (cond[/color]
[color=blue]                      ((getreal[/color]
[color=blue]                             (strcat "\nEnter Distance <"[/color]
[color=blue]                                     (rtos WdwSize 2 2)[/color]
[color=blue]                                     ">: ")))[/color]
[color=blue]                      (WdwSize)))[/color]
 (while (if (null
       (setq
  BoxObj (ssget [color=blue]"_C"[/color]
         sp
         (setq ep (polar sp
           0.785398163
           (* WdwSize 1.412)
    )
         )
         '((0 . "LWPOLYLINE,CIRCLE"))
  )
       )
     )
   (progn
     (if (setq BoxObj (ssget [color=blue]"_C"[/color]
        (setq sp (polar osp 1.57079633 WdwSize))
        (polar sp 0.785398163 (* WdwSize 1.412))
        '((0 . "LWPOLYLINE,CIRCLE"))
        )
        osp    sp
  )
  BoxObj
       (setq BoxObj nil)
     )
   ) BoxObj
 )
   (repeat (sslength BoxObj)
     (setq ent (entget (ssname BoxObj 0)))
     (entmod (subst (cons 8 (setq lnm (strcat "Base_" (itoa cnt))))
      (assoc 8 ent)
      ent
      )
     )
     (if (not (member lnm lylst))
(progn
 (setq lylst (cons lnm lylst)
        lyn (entget (tblobjname "LAYER" lnm)))
       (entmod (subst (cons 62 cnt)(assoc 62 lyn) lyn))))
     (setq BoxObj (ssdel (ssname BoxObj 0) BoxObj))
   )
   (setq sp  (polar sp 0 WdwSize)
  cnt (1+ cnt)
   )
 )

 (princ)
)

 

Entities highlighted at the end of the routine are considered "outsiders" and havent yet decided what to do with it

 

CODE UPDATED

Edited by pBe
Update for No startpoint / proceed prompt
Link to comment
Share on other sites

Thank you, so it's something like what I need. 8)

 

Yes, the window is always a square.

 

res1 the file is the result using its function.

res2 the file is the result I was expecting, there is an entity that was not placed in the new layers and should have been.:unsure:

 

and I also hoped it was not necessary to select the first point, but it was detected automatically, but if not possible will not be the biggest problem.

 

 

 

Thank you in advance for your help

res1.dxf

res2.dxf

Link to comment
Share on other sites

What value did you input for window size?

Draw a square from 0,0 with the window size you just entered. it had to be inisde that window . i drew a square on your sample file and the object on the left upper box is an "outsider" on the third quadrant (see attached)

 

BTW do you want to be prompted for the "Proceed Next Row" input? we can lose that if you want.

 

we can always start at 0,0,0 if thats what you need

 

 

EDIT: POSTED CODE updated

BASE.png

Edited by pBe
Link to comment
Share on other sites

Here is my gif (too big??)

1.jpg

 

I put here also the initial and final file for the example that appears in gif.

 

This file is not the best to explain my problem, because it is very "linear", but I think you can try to explain what I do.

Link to comment
Share on other sites

Seriously, I will tell you right now the way you had those numbers grouped a square box wont work. What you need to consider is the window size.

 

Originally the sample code prompts you for a start point, that way you can somehow dictate where the "scan" will start. you can get away with that for such an example., but then again NOT, an equal LxW selection will more likely give you problems , with a prompt for 2 points for the window size can eliminate that problem.

Link to comment
Share on other sites

sorry, I do not quite understand your post.

in my previous post I tried to put a gif but it seems not work very well.

 

sorry but my English is very bad, and I'm using the translator, which means that sometimes I can not explain very well, I can not understand what I'm trying to say, as was the case in previous post :oops::oops::oops:

 

in my previous post I said I'd put 2 files, but failed and ended up not placing.

 

Now yes, I got the files to see if I understand myself that way, because in words is difficult:cry:

 

The first file is the original and the second is what I intend to get.

placa1.dxf

placa2.dxf

Link to comment
Share on other sites

Maybe if I explain what my goal is easier to understand you guys.

So is this, I'm working with a laser engraving machine, and the recording area is 200x200, or other values ​​depending on the lens I am using. so when I have a drawing area larger than that, I have to go in this area with several layers and then proceed with the recording. I think that this is noticeable which is my goal.

This is one of the functions that I need to have this automated process, which would save me many hours of work. 8)

Link to comment
Share on other sites

I think I understand what he is after.

 

I am not a lisp guy but a way to do it .NET that might resemble a lisp approach would be to do a SelectWindow from 0,0 to 200,200 then change all the entites layers that fall in select window

 

Now do a CrossingWindow from 0,0 to 200,200 and see if any objects are in crossing window compared to previous select window.(To see if any objects only partialy in select window)

 

If there are no new objects the next window will be from 200, 0 to 400, 200.

 

If there were new objects then get the bounding box for each one

for each bounding box that the upper right corner is more than 200 then use the lowest Y value to be the start of the next level.(So if the lowest Y value was 180 then when you move up to next row you start at 0,180)

 

for the rest get the lowest X value to be the start of the next set of windows.

 

In the picture for the first 2 set windows the d is made of 2 different objects so the green part did fully fall in the window and its lowest X value will be the X value of the next window in green.

 

Capture.jpg

 

 

Problems could happen and one for example you need to check if a object has already has layer changed when you move up because a object could fall in more than one window.

 

 

Maybe that will work if the all objects are no larger than a certain size compared to the window. When you get the bounding box if it is area is more than a percentage of the windows area then you show a error message and stop the routine

Link to comment
Share on other sites

In the picture for the first 2 set windows the d is made of 2 different objects so the green part did fully fall in the window and its lowest X value will be the X value of the next window in green.

 

I noticed that too. I was working under the "Too_Large" rule. we could modify selection via "_C" rather than "_W", only thing is it will supersede the "too_large" condition.

 

A quick solution would be create a copy of the entity where it falls in more than one window. that way that entity will be shown on both window (layer)

 

Also from the dxf sample the OP posted, it appears that the 200*200 box did not start at 0,0. so i tested the code with "_C" selection, and its slightly off.

 

If there were new objects then get the bounding box for each one

for each bounding box that the upper right corner is more than 200 then use the lowest Y value to be the start of the next level.(So if the lowest Y value was 180 then when you move up to next row you start at 0,180)

for the rest get the lowest X value to be the start of the next set of windows.

 

too much work ;)

 

 

Posted code updated

 

The attached lisp includes the CopytoPreviousLayer option

SplitToLayers2.LSP

Edited by pBe
Link to comment
Share on other sites

Thank you for your interest in my problem.

 

I've been testing the code pBe provided by and is already close to my goal, one problem is that function only k are selected lwpolilines and circles, but fix it myself with ease.8)

 

a problem that has detected is the question of the entities that are larger than the area defined.

Link to comment
Share on other sites

Thank you for your interest in my problem.

 

I've been testing the code pBe provided by and is already close to my goal, one problem is that function only k are selected lwpolilines and circles, but fix it myself with ease.8)

 

a problem that has detected is the question of the entities that are larger than the area defined.

 

I think we can handle that problem. did you use the one with CopyToPrevousLayer ?

Need to know which one works for you so i can make the necessary adjustments.

and what modifications you did on the code.

Edited by pBe
Link to comment
Share on other sites

Used the function that you put the two posts ago, is necessary to do something to activate this function?

 

a modification that I also needed to do is perform this function also for the layer "Cheio"

but this problem is not too serious because I can duplicate the function and changing its name from the layer it will scan:)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...