U Shaped function

U Shaped function

rpajounia
Advocate Advocate
2,376 Views
25 Replies
Message 1 of 26

U Shaped function

rpajounia
Advocate
Advocate

Is there anyway to make this shape with a function

0 Likes
2,377 Views
25 Replies
Replies (25)
Message 2 of 26

Sea-Haven
Mentor
Mentor

Yes 😂

 

Its a simple object using a pline and extrude. If you just look at how you would use lisp draw some lines and a top arc, then make a pline of these objects, then extrude a good learn lisp task. So please no code people need to learn.

 

Enter length, enter height, that's all that is needed.

0 Likes
Message 3 of 26

rpajounia
Advocate
Advocate

Im making an automated lisp that makes shapes for my nesting program so i cant really make all these shapes 1 by 1 which is why im asking for a lisp and not trying to manually make each object. On average i have 60 shapes every 3 days and dont have the time to make them 1 by 1.

0 Likes
Message 4 of 26

Kent1Cooper
Consultant
Consultant

@Sea-Haven wrote:

....

Enter length, enter height, that's all that is needed.


.... and extrusion thickness. [If that's what you meant by "height," then some other term like "width" of the pre-extruded shape is also needed.]

Kent Cooper, AIA
0 Likes
Message 5 of 26

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

... i cant really make all these shapes 1 by 1 which is why im asking for a lisp and not trying to manually make each object. ... i dont have the time to make them 1 by 1.


If they're not all the same shape so they could just be Copied, a routine is going to need inputs for each one, anyway, so there must be some sort of "1 by 1" aspect to the process.  What is the source of the particulars for each shape?  Would you give the dimensions for each shape, and have the routine just do the forming and extrusion of it?  Are they in something like a spreadsheet file that a routine could read them from?  What would be the criteria for the location of each one?  Are all the shapes of the same kind of "D" shape as in your image, but with differences in sizes/proportions, or are there different varieties of shapes?  If all "D" shaped, could it be done with a Block and different scale factors?  Etc., etc.

 

EDIT:  >Here< is something that could give you some idea how to approach the "D" shape, requiring not-too-complicated adjustment to achieve that rather than the shape it makes:

Kent1Cooper_0-1665407794313.png

 

Kent Cooper, AIA
0 Likes
Message 6 of 26

rpajounia
Advocate
Advocate

Thank you kent sorry guys for not being more exact, the variables that will be given to the function will be with and height ( thickness does not matter ) and what the function will do is make the D shape

0 Likes
Message 7 of 26

Kent1Cooper
Consultant
Consultant

You would also need to decide the orientation of the "D" shape -- as a "D", or [assuming it is done by drawing a Polyline] with the half-circle arc segment on some side other than the right, such as the bottom [given the Topic wording]?  Having determined that, and given dimensions and a starting point, a PLINE command with some (polar) functions, and switching between line and arc segments, and with calculations about the line segment lengths tangent to the arc segment, would not be difficult to construct.

 

There are other things in my previous reply that you will need to address before you can complete a full routine.

Kent Cooper, AIA
0 Likes
Message 8 of 26

rpajounia
Advocate
Advocate

Orientation doesnt really matter i want to give 2 variables, 1 is the bottom line length, 2 is the height of the arc

0 Likes
Message 9 of 26

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

Orientation doesnt really matter i want to give 2 variables, 1 is the bottom line length, 2 is the height of the arc


Given your "bottom line" wording, I'll assume the arc segment on the top [upside-down U, closed].  And I will assume that variable 2 is the height of the arc segment itself plus the length of the vertical line segments tangent to it, that connect it to the bottom line [since for this shape, the height of the arc segment itself must be half the bottom line length, so it would not need to be specified].  There should probably be a check that the specified height is at least half the specified bottom line length.  If it is exactly half the bottom line length, there would be no vertical line segments, and the whole Polyline would be just one line segment and one arc segment.

Kent Cooper, AIA
0 Likes
Message 10 of 26

Sea-Haven
Mentor
Mentor

Yes Kent forgot wanted extruded object, so length, height and thickness would be correct.

 

rpajounia ok a hint can draw a single closed pline with an arc, this is part of the pline command so look carefully at the prompts.

 

Specify next point or [Arc/Close/Halfwidth/Length/Undo/Width]: a

 

Turn Ortho on and draw a pline drag with mouse with say across bottom, enter distance then up and a  distance then an arc then a close.

 

Do it manually with ortho on and can enter lengths, then the arc segment write down each step this is your lisp code sequence.

0 Likes
Message 11 of 26

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

@rpajounia wrote:

.... i want to give 2 variables, 1 is the bottom line length, 2 is the height of the arc


Given your "bottom line" wording, I'll assume the arc segment on the top [upside-down U, closed].  And I will assume that variable 2 is the height of the arc segment itself plus the length of the vertical line segments tangent to it....


Like this?

Kent1Cooper_0-1665492472793.png

That would not be a difficult thing to program a PLINE command to draw, and an extrusion thickness could also be included easily enough if you change your mind from "( thickness does not matter )" in Message 6 back to something like your original image.  But the questions remain about where those values are coming from for all the multiple shapes, how they should be positioned relative to each other, etc.

Kent Cooper, AIA
0 Likes
Message 12 of 26

rpajounia
Advocate
Advocate

Yes your correct my lisp file is reading a text file that is giving the variables and positioning them at (0,0) once all the shapes are drawn it takes the entities and nests them for cutting

0 Likes
Message 13 of 26

Kent1Cooper
Consultant
Consultant

It sounds from more than one of your Messages like you have a routine going already with some of what you want to do.  Adding to it, have it read a line from the text file [what is the format of the information?], start a PLINE command presumably at 0,0, go right by the base dimension, up by the height minus half the base dimension, get into Arc mode and go left by the base dimension, get back into Line mode and Close.  Do you know how to add code to do that kind of thing?

Kent Cooper, AIA
0 Likes
Message 14 of 26

rpajounia
Advocate
Advocate

yes please

0 Likes
Message 15 of 26

Sea-Haven
Mentor
Mentor

Post the text file as a sample and correct dwg that matches. We don't want to keep changing code as information becomes available.

0 Likes
Message 16 of 26

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

Im making an automated lisp ....

....my lisp file is reading a text file....

yes please


Those first two are what suggest to me that you have something started.  There's no point in our starting from scratch if it will duplicate what you have already.  Post that in addition to the sample text file that @Sea-Haven requested.

 

What was the third line above in reply to?

Kent Cooper, AIA
0 Likes
Message 17 of 26

rpajounia
Advocate
Advocate

Yes please was targeted as you got what i would like as correct. I would like x = 10 y = 10 z = 5 and it output this diagram y = height of diagram with arc

0 Likes
Message 18 of 26

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:

.... I would like x = 10 y = 10 z = 5 ....


That does not help unless you intend to type in values individually for all the shapes, which Message 3 says you do not.  You have mentioned, but [after several requests] not yet posted an example of, a text file from which the values would be read, nor have we seen whatever code you have already.

Kent Cooper, AIA
0 Likes
Message 19 of 26

rpajounia
Advocate
Advocate

Code is below im making a function now for UShape and and i will put a if statement to check for that next

 

 

(defun c:DrawLayout2 (/ Thickness WidthText Width a b c ab bc DidLines 1InchList 2InchList 3InchList 4InchList 5InchList 6InchList)
      (setq p1 '(-1500. -1000. 0.))
      (setq p2 '(8000.0 5000.0 0.0))
      (command "._zoom" "_w" "_non" p1 "_non" p2) ; end zoom
      (princ)
      (setq DidLines 0)
      (setq 1InchList (ssadd))
      (setq 2InchList (ssadd))
      (setq 3InchList (ssadd))
      (setq 4InchList (ssadd))
      (setq 5InchList (ssadd))
      (setq 6InchList (ssadd))
      (setq 1InchList84x96 (ssadd))
      (setq 2InchList84x96 (ssadd))
      (setq 3InchList84x96 (ssadd))
      (setq 4InchList84x96 (ssadd))
      (setq 5InchList84x96 (ssadd))
      (setq 6InchList84x96 (ssadd))
      ;(setq des2 (open (strcat "C:\\Users\\Raymons\\Desktop\\Customs ISO\\CustomCut.xml") "r"))
      (setq des2 (open (strcat "C:\\Users\\RPajo\\OneDrive\\Desktop\\Customs\\CustomCut.xml") "r"))
      (while (and (setq line (read-line des2)))
            (setq Thickness (substr line 1 (vl-string-position (ascii "x") line )))
            (setq WidthText (vl-string-subst "" (strcat Thickness "x") line))
            (setq Width (substr WidthText 1 (vl-string-position (ascii "x") WidthText )))
            (if (vl-string-search "Circle" line)
              (progn

                  (setq Width (substr WidthText 1 (vl-string-position (ascii "Circle") WidthText )))
                  (setq QuantityText (vl-string-subst "" (strcat Thickness "x" Width "Circle ( 1.8 Density / 44 ILD ) ") line))
                  (setq Quantity (substr QuantityText 1 (vl-string-position (ascii " ") QuantityText )))
                  (repeat (read Quantity)
                    (if (<= (read Width) 72)
                        (progn
                              (if (= (read Thickness) 1)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 1InchList)
                                )
                              )
                              (if (= (read Thickness) 2)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 2InchList)
                                )
                              )
                              (if (= (read Thickness) 3)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 3InchList)
                                )
                              )
                              (if (= (read Thickness) 4)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 4InchList)
                                )
                              )
                              (if (= (read Thickness) 5)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 5InchList)
                                )
                              )
                              (if (= (read Thickness) 6)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 6InchList)
                                )
                              )
                         )
                        (progn
                              (if (= (read Thickness) 1)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 1InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 2)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 2InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 3)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 3InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 4)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 4InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 5)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 5InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 6)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 6InchList84x96)
                                )
                              )
                         )
                      )
                  )
              )
              (progn
                  (if (vl-string-search "Trap" line)
                    (progn
                          (setq LengthText (vl-string-subst "" (strcat Thickness "x" Width "x") line))
                        (setq Length1 (substr LengthText 1 (vl-string-position (ascii "x") LengthText )))
                        (setq OverCutText (vl-string-subst "" (strcat Thickness "x" Width "x" Length1 "x") line))
                        (setq OverCut (substr OverCutText 1 (vl-string-position (ascii "x") OverCutText )))
                        (setq BumpText (vl-string-subst "" (strcat Thickness "x" Width "x" Length1 "x" OverCut "x") line))
                        (setq Bump (vl-string-subst "" "Trap" (substr BumpText 1 (vl-string-position (ascii " ") BumpText ))))
                        (setq QuantityText (vl-string-subst "" (strcat Thickness "x" Width "x" Length1 "x" OverCut "x" Bump "Trap ( 1.8 Density / 44 ILD ) ") line))
                        (setq Quantity (substr QuantityText 1 (vl-string-position (ascii " ") QuantityText )))
                        (setq  p1 (list 0 0 0)
                               p2 (list (* (read Length1) 25.4) (* (read Width) 25.4) ))
                        
                        (repeat (read Quantity)
                              (if (<= (read Width) 72)
                                (progn
                                    (if (= (read Thickness) 1)
                                      (progn
                                        (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4) ) 1InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 2)
                                      (progn
                                         (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 2InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 3)
                                      (progn
                                         (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 3InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 4)
                                      (progn
                                        (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 4InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 5)
                                      (progn
                                         (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 5InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 6)
                                      (progn
                                        (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 6InchList)
                                      )
                                    )
                                 )
                                (progn
                                    (if (= (read Thickness) 1)
                                      (progn
                                        (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 1InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 2)
                                      (progn
                                         (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 2InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 3)
                                      (progn
                                         (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 3InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 4)
                                      (progn
                                        (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 4InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 5)
                                      (progn
                                         (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 5InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 6)
                                      (progn
                                        (ssadd (_trap p1 p2 (* (- (read Length1) (read OverCut)) 12.7) (* (read Bump) 25.4)) 6InchList84x96)
                                      )
                                    )
                                )
                              )
                          )
                    )
                    (progn
                        (setq LengthText (vl-string-subst "" (strcat Thickness "x" Width "x") line))
                        (setq Length1 (substr LengthText 1 (vl-string-position (ascii " ") LengthText )))
                        (setq QuantityText (vl-string-subst "" (strcat Thickness "x" Width "x" Length1 " ( 1.8 Density / 44 ILD ) ") line))
                        (setq Quantity (substr QuantityText 1 (vl-string-position (ascii " ") QuantityText )))
                        (setq  p1 (list 0 0 0)
                              p2 (list (* (read Length1) 25.4) (* (read Width) 25.4) ))
                        (repeat (read Quantity)
                              (if (<= (read Width) 72)
                                (progn
                                    (if (= (read Thickness) 1)
                                      (progn
                                        (ssadd (_rect p1 p2) 1InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 2)
                                      (progn
                                         (ssadd (_rect p1 p2) 2InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 3)
                                      (progn
                                         (ssadd (_rect p1 p2) 3InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 4)
                                      (progn
                                        (ssadd (_rect p1 p2) 4InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 5)
                                      (progn
                                         (ssadd (_rect p1 p2) 5InchList)
                                      )
                                    )
                                    (if (= (read Thickness) 6)
                                      (progn
                                        (ssadd (_rect p1 p2) 6InchList)
                                      )
                                    )
                                 )
                                (progn
                                    (if (= (read Thickness) 1)
                                      (progn
                                        (ssadd (_rect p1 p2) 1InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 2)
                                      (progn
                                         (ssadd (_rect p1 p2) 2InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 3)
                                      (progn
                                         (ssadd (_rect p1 p2) 3InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 4)
                                      (progn
                                        (ssadd (_rect p1 p2) 4InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 5)
                                      (progn
                                         (ssadd (_rect p1 p2) 5InchList84x96)
                                      )
                                    )
                                    (if (= (read Thickness) 6)
                                      (progn
                                        (ssadd (_rect p1 p2) 6InchList84x96)
                                      )
                                    )
                                )
                              )
                          )
                      )
                  )
              )
            )
        (setq DidLines (1+ DidLines))
      )
)

(defun _rect (p1 p2 / lt point2d x1 y1 x2 y2 pts q)
      (defun lt (pt) (trans pt 1 0))
      (defun point2d (pt) (list (car pt) (cadr pt)))
        ;(command "_.ucs" "w")
      (setq
            x1 (apply 'min (mapcar 'car (list p1 p2)))
            y1 (apply 'min (mapcar 'cadr (list p1 p2)))
            x2 (apply 'max (mapcar 'car (list p1 p2)))
            y2 (apply 'max (mapcar 'cadr (list p1 p2)))
          pts (mapcar 'point2d(mapcar 'lt (list (list x1 y1) (list x2 y1) (list x2 y2) (list x1 y2))))
      )
      (cond
            ((and pts)
                  (setq q (entmakex
                        (apply 'append
                              (cons
                                (list
                                    '(0 . "LWPOLYLINE")
                                    '(100 . "AcDbEntity")
                                    '(100 . "AcDbPolyline")
                                    '(410 . "Model")
                                    '(8 . "0")
                                    '(38 . 0)
                                    '(62 . 256)
                                    '(67 . 0)
                                    (cons 90 (length pts))
                                    '(70 . 1)
                                )
                                (mapcar 'list (mapcar '(lambda (a) (cons 10 a)) pts))
                              )
                        )
                  ))
            )
      )
      q
)

(defun _circl (p1 / lt point2d x1 y1 x2 y2 pts q)
      (setq q (entmakex (append (list (cons 0 "CIRCLE") (cons 10 (list 0 0 0)) (cons 40 p1)))))
      q
)

(defun _trap (p1 p2 p3 p4 / lt point2d x1 y1 x2 y2 pts q)
      (defun lt (pt) (trans pt 1 0))
      (defun point2d (pt) (list (car pt) (cadr pt)))
        ;(command "_.ucs" "w")
      (princ "doing setq")
      (setq
            x1 (apply 'min (mapcar 'car (list p1 p2)))
            y1 (apply 'min (mapcar 'cadr (list p1 p2)))
            x2 (apply 'max (mapcar 'car (list p1 p2)))
            y2 (apply 'max (mapcar 'cadr (list p1 p2)))
          pts (mapcar 'point2d(mapcar 'lt (list (list x1 y1) (list x2 y1) (list x2 (+ y1 p4) ) (list (- x2 p3) y2) (list (+ x1 p3) y2) (list x1 (+ y1 p4) ) )))
      )
 
      (cond
            ((and pts)
                  (setq q (entmakex
                        (apply 'append
                              (cons
                                (list
                                    '(0 . "LWPOLYLINE")
                                    '(100 . "AcDbEntity")
                                    '(100 . "AcDbPolyline")
                                    '(410 . "Model")
                                    '(8 . "0")
                                    '(38 . 0)
                                    '(62 . 256)
                                    '(67 . 0)
                                    (cons 90 (length pts))
                                    '(70 . 1)
                                )
                                (mapcar 'list (mapcar '(lambda (a) (cons 10 a)) pts))
                              )
                        )
                  ))
            )
      )
      q
)
0 Likes
Message 20 of 26

Kent1Cooper
Consultant
Consultant

@rpajounia wrote:
....
                    (if (<= (read Width) 72)
                        (progn
                              (if (= (read Thickness) 1)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 1InchList)
                                )
                              )
                              (if (= (read Thickness) 2)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 2InchList)
                                )
                              )
                              (if (= (read Thickness) 3)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 3InchList)
                                )
                              )
                              (if (= (read Thickness) 4)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 4InchList)
                                )
                              )
                              (if (= (read Thickness) 5)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 5InchList)
                                )
                              )
                              (if (= (read Thickness) 6)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 6InchList)
                                )
                              )
                         )
                        (progn
                              (if (= (read Thickness) 1)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 1InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 2)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 2InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 3)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 3InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 4)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 4InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 5)
                                (progn
                                   (ssadd (_circl (* (read Width) 12.7)) 5InchList84x96)
                                )
                              )
                              (if (= (read Thickness) 6)
                                (progn
                                  (ssadd (_circl (* (read Width) 12.7)) 6InchList84x96)
                                )
                              )
                         )
                      )
....

We still haven't seen the nature of the content of the text file you're pulling information from.

 

But in any case, your code can be greatly reduced in a variety of ways.

You have unnecessary (progn) "wrappers" around things that don't need them [single functions -- mostly (ssadd) -- used as 'then' arguments in (if) functions, where (progn) is needed only when multiple functions together are needed as the single 'then' or 'else' argument].

You have conversions of strings to non-text that you don't need, such as:

  (if (= (read Thickness) 1)

when you could just do:

  (if (= Thickness "1")

You have multiple (if) functions that would be better handled with (cond) functions [but the following would eliminate a lot of that anyway].

 

Any time the same code is repeated multiple times, there's probably a way to reconfigure things to contain it fewer times, or even just once.  One of the more extreme examples is that [I believe -- untested] the entire excerpt quoted above can be replaced with just this:

 

(ssadd
  (_circl (* (read Width) 12.7))
  (read (strcat Thickness "InchList" (if (> (read Width) 72) "84x96" "")))
)

 

and similarly for the "Trap" portion and the (_rect) portion if it's not "Circle" or "Trap."

 

Speaking of which, if you use a RECTANG command, it's not necessary to convert points between the current UCS and the WCS, nor to convert them to XY only coordinates, nor to calculate the other two corners.  Your (_circ1) function doesn't specify model space or Layer 0 as the (_rect) and (_trap) functions do, so if I can assume you are there when you run this, or it doesn't really matter if the objects are just drawn on the current Layer, you should be able to replace the (_rect) function with just this:

 

(defun _rect (p1 p2)
  (command "_.rectang" "_non" p1 "_non" p2)
  (setq q (entlast))
)

 

Yes, it "takes longer," but you would need to be making a very large number of them for that to make a meaningful difference.

Kent Cooper, AIA
0 Likes