.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Block Calculation

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
k005
736 Views, 8 Replies

Block Calculation

Hello to everyone

How can I multiply the texts in this format > SZ01 (30/60) within the selected blocks?

I want to calculate the volume by multiplying and adding the parenthesized expressions in the block and multiplying by 15.

 

Details are in the sample file.

I am attaching the sample file.

8 REPLIES 8
Message 2 of 9
3wood
in reply to: k005

For your blocks, you can try following steps:

1. EXPLODE blocks

2. JOIN lines as polyline

3. BHATCH all polyline 

4. LIST the last object to get the total area.

AREA.gif

Message 3 of 9
k005
in reply to: 3wood

Hi @3wood ,

 

Thank you for the answer. I already have the solution you described...

 

I want to go to the solution by using a parameter like */* without exploding.

 

So we're not going to explode.

Message 4 of 9
_gile
in reply to: k005

Hi,

Given all the help you have received regarding retrieving numbers in strings with regular expressions (Regex), you should be able to solve this problem by yourself.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 9
k005
in reply to: _gile

@_gile 

 

Yes. I solved only text object case with regex. This will be a second addition... so calculating for Block...

Message 6 of 9
3wood
in reply to: k005

Please try the lisp below:

TAFT.gif

;;; TAFT.lsp by 3wood
;;; Calculate total area from text in select blocks. Texts need in a format of "SZ01 (30/60)".
;;; https://forums.autodesk.com/t5/net/block-calculation/m-p/10798183#M71113

(defun C:TAFT (/ b1 i1 p1 p2 p3 p4
	       RESULT s1 t1 )
  (setq s1 (ssget '((0 . "INSERT")))
	RESULT 0.0)
  (repeat (setq i1 (sslength s1))
    (setq i1 (1- i1))
    (vlax-for b1 (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) (vla-get-name (vlax-ename->vla-object (ssname s1 i1))))
      (if (and (equal (vla-get-ObjectName b1) "AcDbText")
	       (setq t1 (vla-get-textstring b1)
		     p1 (vl-string-search "(" t1)
		     p2 (vl-string-search "/" t1)
		     p3 (vl-string-search ")" t1))
	       )
	(setq RESULT (+ RESULT  (* (* (atof (substr t1 (+ p1 2) (- p2 p1 1))) (atof (substr t1 (+ p2 2) (- p3 p2 1)))) 0.0001)))
	)
      )
    )
  (setq P4 (getpoint "\nPick up point:"))
  (vl-cmdf "text" P4 "0.39" "0.0" (strcat "Hacim : "(rtos RESULT 2 2)" m\U+00B2 x 15 = " (rtos (* RESULT 15.0) 2 2) " m\U+00B3"))
  )

 

 

Message 7 of 9
_gile
in reply to: k005

Here is an F# code that works.
I think it's self-explanatory enough that you should know how to convert it to C#.

module TestFsharp.Commands

open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Runtime

type AcCoreApp = Autodesk.AutoCAD.ApplicationServices.Core.Application
type AcExn = Autodesk.AutoCAD.Runtime.Exception

// =================================== HELPERS ==================================== //

module Active =
    let doc = AcCoreApp.DocumentManager.MdiActiveDocument
    let db = doc.Database
    let ed = doc.Editor

let getTopTransaction (db: Database) =
    match db.TransactionManager.TopTransaction with
    | null -> raise (AcExn(ErrorStatus.NoActiveTransactions))
    | tr -> tr

let getObject<'T when 'T 😆 DBObject> mode (id: ObjectId) =
    let tr = getTopTransaction id.Database
    tr.GetObject(id, mode) :?> 'T

let getObjects<'T when 'T 😆 DBObject> mode (ids: System.Collections.IEnumerable) =
    let rx = RXObject.GetClass typeof<'T>
    ids
    |> Seq.cast<ObjectId>
    |> Seq.choose (fun id ->
        if id.ObjectClass.IsDerivedFrom rx then Some(getObject<'T> mode id) else None)

// ===================================== MAIN ====================================== //

open System.Text.RegularExpressions

let rgx = Regex(@"^SZ\d+ \((\d+)/(\d+)\)$")

let getArea (btr: BlockTableRecord) =
    btr
    |> getObjects<DBText> OpenMode.ForRead
    |> Seq.map (fun t -> t.TextString)
    |> Seq.pick (fun s ->
        let groups = rgx.Match(s).Groups
        if groups.Count = 3 then 
            Some ((groups.[1].Value |> float) * (groups.[2].Value |> float) * 0.0001) 
        else 
            None)

[<CommandMethod("TEST")>]
let test() = 
    let ss = 
        Active.ed.GetSelection(SelectionFilter([| 
            TypedValue(0, "INSERT")
            TypedValue(2, "IDE723Entity*") |]))
    if ss.Status = PromptStatus.OK then
        use tr = Active.db.TransactionManager.StartTransaction()
        let area =
            ss.Value.GetObjectIds()
            |> getObjects<BlockReference> OpenMode.ForRead
            |> Seq.map (fun br -> 
                br.BlockTableRecord |> getObject<BlockTableRecord> OpenMode.ForRead)
            |> Seq.sumBy getArea
        let ppr = Active.ed.GetPoint("\nInsertion point: ")
        if ppr.Status = PromptStatus.OK then   
            let text = new DBText()
            text.Position <- ppr.Value.TransformBy(Active.ed.CurrentUserCoordinateSystem)
            text.TextString <- sprintf "Hacim = %.2f m² x 15 = %.2f m\U+00B3" area (area * 15.)
            text.Height <- 0.4
            let cSpace = getObject<BlockTableRecord> OpenMode.ForWrite Active.db.CurrentSpaceId
            cSpace.AppendEntity(text) |> ignore
            tr.AddNewlyCreatedDBObject(text, true)
            tr.Commit()

 

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 9
k005
in reply to: 3wood

@3wood 

 

Thank you very much, very nice work. good luck to you.

Message 9 of 9
k005
in reply to: _gile

@_gile 

 

Since you gave F#. Can I get information about the difference and usage of this from C# code?


I think I can translate this example to C#... Thank you.

 

If I translate, I will give solution approval.

 

************************************************************************************************************

 

 

More confused.. 😞 What is F#?

 

1- I understood the active part of the module.
2- I understood the regex part.
3- I understood a little bit in Command TEST.

 

but that's all...


*I also forgot to write. We will take the values into the listbox in their current form.

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


AutoCAD Beta