Author Topic: DesignCad drives me crazy  (Read 3271 times)

Juergen

  • Jr. Member
  • **
  • Posts: 94
DesignCad drives me crazy
« on: December 06, 2014, 07:20:03 AM »
I'm trying to delete a text in a (imported DXF-) selection.
This works fine on V21 and V22 - V23 fails even the V23 dll is loaded.

           
         
         success = DcFile.ImportDXF(strFileName)
         
         Dim SelCount As Long
         Dim i As Long

         DcSel = DcDoc.Selection
         
         For i = 1 To SelCount
                DcEnt = DcSel.Item(i)
                If DcEnt.EntityType = 402 Then   'remove 2D text
                    DcEnt = DcSel.Item(i)
                    DcEnt.Delete()  ' Crash in V23, V21 and V22 are fine
                End If
            Next i
         

Is this kismet? Does anyone have an idea for a workaround?
Prl - I hear the siren singing all the time :(

Kind regards,

Juergen

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #1 on: December 06, 2014, 10:12:57 AM »
Juergen,  the following procedure works for me in versions 22 and 23.  It is using the Type library from version 22, so I'm not recompiling for version 23.

The syntax is pascal.

procedure TForm1.Button1Click(Sender: TObject);
var
  SelCount, i: integer;
begin
  SelCount := DcSel.Count;
  for i := 1 to SelCount do begin
    DcEnt := DcSel.Item(i);
    if DcEnt.EntityType = 402 then DcEnt.Delete;
  end;
  DcSel.DeSelectAll;
  DcDoc.Views.RegenerateAll;
end;
(*----------------------------------------------------------------------------*)



A General Tip/Trick

Also because of the slowness of OLE, a trick I do is to embed basiccad routines in hidden memo controls in my OLE program.  Then when I want to do something intensive, I have the OLE write the basiccad routine to disk.  You can have your OLE program do it at Form.Show.  Then also have it do a clean-up (destroy the various helper macros) when you close your application (FormClose). The intention being to use the OLE for the GUI items and basiccad for the heavy data processing and looping.  Basiccad is many many times faster and easier to debug.  OLE suffers from trying to push hundreds of gallons of information through a straw.
« Last Edit: December 06, 2014, 06:49:47 PM by prl »

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #2 on: December 06, 2014, 06:25:00 PM »
Juergen, here is a way to import the dxf, explode the block, and quickly set the colorbylayer flag to False.  It uses the embedded basiccad routine trick.  I've attached the routine (cbe.d3m).

A movie - using BasicCAD within an OLE to QUICKLY process entities (since OLE is DOG SLOW)
(Reminder: In the movie, you can left click in the movie area to start/stop the action.  And the slider to rewind.)

« Last Edit: December 07, 2014, 05:29:29 AM by prl »

Juergen

  • Jr. Member
  • **
  • Posts: 94
Re: DesignCad drives me crazy
« Reply #3 on: December 07, 2014, 02:40:04 AM »
Hey Prl,

thanks again for the solution, your time and all the work you have done for me!
That's not to be taken for granted. I very much appreciate your effort.

Text removing with if DcEnt.EntityType = 402 then DcEnt.Delete; still fails with
DC V23 (crash). I tried dll 21,22,23.

I am not so familiar with BasicCad. Is there a statement to delete an item?
Something like this:
------------------------------
maxsel = sys(80)

'get entity numbers and store in array
for j = 1 to maxsel
  getselect j, entid
  entity entid
 
If  Sys(90) = 13 Then
  >DELETE/REMOVE THIS TEXT ?????
{
}

End If
   
  change Ent_ColorByLayer, 0
next j
--------------------------------

BTW: In terms of your Delphi example: It is not for sure that the text is always the
last entry (DcSel.SelectLast / DCSel.Erase).

Kind regards,

Juergen
« Last Edit: December 07, 2014, 02:42:09 AM by Juergen »

Juergen

  • Jr. Member
  • **
  • Posts: 94
Re: DesignCad drives me crazy
« Reply #4 on: December 07, 2014, 03:42:01 AM »
For now this is my first working approach:

Alias T_TEXT              &H050A
If  Sys(90) = 13 Then
Change T_Text, " "
End If

Kind regards,

Juergen

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #5 on: December 07, 2014, 04:01:35 AM »
Juergen,  two things.  The code you have in your original post is missing where you define the SelCount.  If you compare my pascal to your VB, that's about the only thing different. So try fixing that and see if it works.  But it will still be slow.

With regards to basiccad, do you want to delete all 2d text in the selection set quickly?  If yes, I'll show you the basiccad code for that. 

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #6 on: December 07, 2014, 04:38:03 AM »
Here is some more info for you to consider.

1.  I recompiled that sample project (in the movie in reply #2) using the DC TLB type library from version 16.  Then I tested the OLE on versions 16 to 24.  Works on my machine and my DC versions.  So that coding is independent of versions which always helps.  I dislike having to recompile OLE programs for each version.  I attempt neutral OLE version programming.  Can't always do that, but I aim for it.

2. Create a entity heavy drawing with some 2d text here and there.  Select all, then hit the button. The selection/text delete test shows you how slow OLE looping is.


Pascal Source Code - The code for that sample OLE program.  It has two buttons, one for the selection testing the other for the dxf importing testing.

The OLE executable - The sample compiled OLE program for you to try. Try it with different DC versions.  Works for me, maybe for you?
« Last Edit: December 07, 2014, 04:42:31 AM by prl »

Juergen

  • Jr. Member
  • **
  • Posts: 94
Re: DesignCad drives me crazy
« Reply #7 on: December 07, 2014, 07:20:57 AM »
Hi Prl,

your .exe fails on V23 with "Command failed". The dxf is then not grouped, the text is not removed.
V21 works fine. It's not worth to work any longer on this topic. The BasicCad solution is better and
faster! Thanks.

Please read urgently your pm - there is a new message.

Kind regards,

Juergen

Juergen

  • Jr. Member
  • **
  • Posts: 94
Re: DesignCad drives me crazy
« Reply #8 on: December 07, 2014, 07:32:02 AM »
Quote
The code you have in your original post is missing where you define the SelCount.

It's in the code, but not in the published snippet.

Quote
With regards to basiccad, do you want to delete all 2d text in the selection set quickly?  If yes, I'll show you the basiccad code for that.
 

Actually I'm fine with this solution ' Change T_Text, " " ' - Please let me know in case there is a better solution available. I want to delete all 2d text entries.

BTW: Please take a look at the attachment (same password). I guess there is no way to remove vector-text?

Kind regards,

Juergen

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #9 on: December 07, 2014, 07:58:07 AM »
I want to delete all 2d text entries.

Code: [Select]
'program   k13.d3m (kill type 13 entities - GLOBAL TO DRAWING)

'12/7/2014 - an ole embed routine

'Note to Juergen - this will delete all type 13 entities in the drawing whether selected or not.

sys(36)=2
curstate = sys(231)
sys(231) = 0 'turn it off, it flashes and slows the processing loop

'note - this will add the type 13 to the selection set
>EntitySelect
{
<Type 13
}                                                     

if sys(80) >0 then
  >erase
  {
  }
endif
sys(36)=0

regen
sys(231)=curstate 'restore original infobox state

END
« Last Edit: December 07, 2014, 09:12:51 AM by prl »

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #10 on: December 07, 2014, 08:02:00 AM »
If you want to delete all the 2d text entries ONLY IN SELECTION SET, see below.

Code: [Select]
'program   k13ss.d3m (kill type 13 entities in SELECTION SET)

'12/7/2014 - an ole embed routine

'Note to Juergen - this will delete all type 13 entities in the SELECTION SET

dim ent(10000)
curstate = sys(231)
sys(36)=2
sys(231) = 0 'turn it off, it flashes and slows the processing loop

maxsel = sys(80)

for j = 1 to maxsel
  getselect j, ent(j) 'get entity numbers and store in array
next j

sys(80)=0
 
for i = 1 to maxsel
  GetAttr ent(i), type, select
  if type = 13 then PutAttr ent(i), type, 1
next i

if sys(80) >0 then
  >erase
  {
  }
endif

sys(36)=0

regen
sys(231)=curstate 'restore original infobox state

END
« Last Edit: December 07, 2014, 09:12:23 AM by prl »

DrollTroll

  • Kindly Curmudgeon
  • Administrator
  • *****
  • Posts: 4152
Re: DesignCad drives me crazy
« Reply #11 on: December 08, 2014, 07:34:15 AM »
General advice (both for OLE Automation and for BasicCAD) -- watch your looping behavior, and make sure your routine isn't altering the contents of the set being worked on.

Particularly, if you're deleting items from a selection set, I strongly recommend counting DOWN through the selection indices, rather than UP, especially if you're storing the initial set count in a variable and using that variable as your loop counter.

Example: your routine identifies and deletes item 2 of the selection set. What *was* item-index 3 is now drops to item-index 2, but it will be skipped because your loop is moving on to 3. What was item-index maxsel no longer exists, so attempting to load it may indeed cause a crash. On the other hand, if you count DOWN while deleting objects, you're only affecting the current index and above; the previous indices will remain unaffected and can still be accessed by your loop counter.

There could be other situations where looping-while-operating-on-things may set you up for unexpected behavior, but the one above has certainly given me many forehead-slap moments.
« Last Edit: December 08, 2014, 07:36:06 AM by DrollTroll »
25 years with DesignCAD

Juergen

  • Jr. Member
  • **
  • Posts: 94
Re: DesignCad drives me crazy
« Reply #12 on: December 08, 2014, 08:01:00 AM »
Hi Prl,

thanks again for your endless help!

'program   k13.d3m and 'program   k13ss.d3m

I want to erase the 2d text in the actual selection. Using your cbe-macro
I am going to integrate the PUTATTR Statement there, because there is actual
a step through active to change Ent_ColorByLayer. This looks like this now:

'get entity numbers and store in array
for j = 1 to maxsel
  getselect j, entid
  entity entid
  If  Sys(90) = 13 Then PutAttr entid, type, 1
  change Ent_ColorByLayer, 0
next j


@DrollTroll
Thanks for this advice. I'll set now

for j =  maxsel to 1 Step -1

Kind regards,

Juergen,  having had multiple forehead-slap moments.  :'(
« Last Edit: December 08, 2014, 09:19:24 AM by Juergen »

prl

  • Hero Member
  • *****
  • Posts: 3389
  • A Bézier Extrusion
Re: DesignCad drives me crazy
« Reply #13 on: December 08, 2014, 09:56:40 AM »
for j = 1 to maxsel
  getselect j, entid
  entity entid
  If  Sys(90) = 13 Then PutAttr entid, type, 1
  change Ent_ColorByLayer, 0
next j

That works.  A slight modification so your type variable holds the proper value.  (It is possible to quickly change a plane to a line by looping and changing the type from 31 to 1).

for j = 1 to maxsel
  getselect j, entid
  entity entid
  type = sys(90)
  If  type = 13 Then PutAttr entid, type, 1
  change Ent_ColorByLayer, 0
next j
« Last Edit: December 08, 2014, 11:10:21 AM by prl »

Juergen

  • Jr. Member
  • **
  • Posts: 94
Re: DesignCad drives me crazy
« Reply #14 on: December 08, 2014, 10:11:59 AM »
Prl,

  type = sys(90)
  If  type = 13 Then PutAttr entid, type, 1

fails (text not removed), this works

  typetokill = sys(90)
  If  typetokill = 13 Then PutAttr entid, type, 1

I guess type is reserved as part of the statement:

PUTATTR entity, type, {,select, laynum, group, red, green, blue, solid}

May be "If  typetokill = 13 Then PutAttr entid, 0, 1" is better as type is not defined clearly ?

Kind regards,

Juergen

« Last Edit: December 08, 2014, 10:42:11 AM by Juergen »