Author Topic: ==={Challenge}===Find the ridge lines of sloped roof  (Read 106663 times)

0 Members and 1 Guest are viewing this topic.

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #60 on: February 08, 2014, 07:52:14 AM »
GP, I've modified your code just a little... I used to model 3D roof according to slope angle, so I've added this to have these 2 options available when 3D mode is choosen... Also I've put (vl-load-com) inside main code as I implemented it into my Startup Suite (I don't want (vl-load-com) to be automatically initialized - of course this is possible only in lower A versions which I happen to poses them on my netbook)... This helps me to better understand functions that are (vl-load-com) independent and if possible I always tend to make code firstly Vanilla varsions of code if possible and only if it's neccessity then I use VLISP... So this is my version (your lisp) that I autoload...

Hope you don't mind I post it...

M.R.

[EDIT : Code updated finally]
« Last Edit: May 25, 2014, 04:55:06 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #61 on: February 08, 2014, 03:45:14 PM »
I think I solved this problem with modeling operation failures... It was that fact that ACAD creates additional 3DSOLIDs after command SOLIDEDIT "face" "move"... So I didn't realize that GP didn't analyzed my roof.lsp routine thorough and deeply... I've solved earlier how to get rid of additional 3DSOLIDs so that only valid 3DSOLID solution remains...

So my previously attached hr.lsp reattached with this mods... I hope that now it'll not fail in any situation that may occur... If that's the case, please inform here with problematic POLYLINE... Hope that this will be my final post ab this topic, unless someone finds good 2D solution code that may be used in learning purposes like I posted my codes, but none of them isn't 100% reliable...

Regards, M.R. and enjoy with GP's hr.lsp
 :wink:
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #62 on: February 09, 2014, 03:08:46 AM »
It seems that it was again me who firstly found wrong POLYLINE... Now I don't know what to do with this kind of entity (POLYLINE)... It seems that we seriously have to find alternative method for this problem...

See attached DWG... Simply unbelievable...
M.R.
« Last Edit: February 09, 2014, 03:22:48 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #63 on: February 09, 2014, 08:34:33 AM »
Like I described to GP what method I used to construct 3D roof from 2D solution, I've decided to automate this process and I succeeded... The result is somewhat modified GP's code (mainly his subfunctions used) - 2droof3d.lsp

HTH, M.R.

So now back to the job... Task Challenge - Find 2D solution of picked LWPOLYLINE...

[EDIT : During some of my tests, I've noticed that 2droof3d.lsp sometimes fails if in line (command "_.ucs" "_3p") haven't been provided points without "_non" preference... So I've added this small issue into these 2 lines... There were total of 13 downloads till I reattached 2sroof3d.lsp]

[EDIT : Testing failed in some situations... Old routine is now 2droof3d-old.lsp (previously named 2droof3d.lsp) and new one is 2droof3d.lsp - new version ask explicitly that LWPOLYLINE must be CCW oriented otherwise reverse it and retry...]

[EDIT : I've found where was my mistake - it was sub-function ListCloskwise-p and that's now fixed... Previous version is now 2droof3d-new-old.lsp (previously named 2droof3d.lsp) and new one is 2droof3d.lsp - new version doesn't need LWPOLYLINE oriented in CCW - it should work in both cases...]

Sorry for inconvenience. M.R.
« Last Edit: March 15, 2014, 05:42:16 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #64 on: February 11, 2014, 05:29:00 AM »
I worked just a little more ab this 2D solutions and yesterday I've made this code... It is with approximately good results, also not 100% reliable, but I must warn you - it is the slowest code I ever made... So if you have example that's not to complex, and soultion is unique - no additional roof porches and you have a time to experiment you can try it... But it's not 100% correct also... My recomendations is to use last code I posted to Evgeniy, if you're not satisfied then try first code posted in [ code ] tags - not [ code=cadlisp-7 ] tags, and if you again aren't satisfied and if you have time and strong computer only then try this code... My motives for posting this one is that fact that it introduces few new sub-functions that may be useful and are related to this task... So I warned you - this isn't the worst code, but certainly the slowest one... Be careful with your time - maybe someone can do it manually faster...

Code: [Select]
(defun 2droof (pol / ListDupes valid-inscribed-circle-p inscribed-circle insidep unique _vl-remove ridge onlin-p assocon prelst suflst ll pl pln i rl tl v v1 v2 vl vp vp1 vp2 vpp1 vpp2 vpl vrl vtl vx)

  (defun ListDupes (l / x r)
    (while l
      (if (vl-member-if '(lambda (a) (equal a (setq x (car l)) 1e-10)) (cdr l))
        (setq r (cons x r))
      )
      (setq l (vl-remove x (cdr l)))
    )
    (reverse (acet-list-remove-duplicates r 1e-6))
  )

  (defun valid-inscribed-circle-p (p pol / plst xl xll ip ipp dstl)
    (setq
      plst (mapcar '(lambda (x) (list (car x) (cadr x) 0.0))
                   (mapcar 'cdr (acet-list-m-assoc 10 (entget pol)))
           )
    )
    (mapcar '(lambda (a b)
               (progn (setq xl
                             (entmakex (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 a) (cons 11 (unit (mapcar '- b a)))))
                      )
                      (setq xll (cons xl xll))
               )
             )
            plst
            (cdr (reverse (cons (car plst) (reverse plst))))
    )
    (foreach x xll
      (setq ip (vlax-curve-getclosestpointto x p))
      (setq ipp (cons ip ipp))
    )
    (setq dstl (mapcar '(lambda (x) (distance x p)) ipp))
    (foreach x xll
      (entdel x)
    )
    ;(foreach r (ListDupes dstl)
    ;  (entmake (list '(0 . "CIRCLE") (cons 10 (list (car p) (cadr p) 0.0)) (cons 40 r)))
    ;)
    (if (ListDupes dstl) t nil)
  )

  (defun inscribed-circle (p pol / plst xl xll ip ipp dstl)
    (setq
      plst (mapcar '(lambda (x) (list (car x) (cadr x) 0.0))
                   (mapcar 'cdr (acet-list-m-assoc 10 (entget pol)))
           )
    )
    (mapcar '(lambda (a b)
               (progn (setq xl
                             (entmakex (list '(0 . "XLINE") '(100 . "AcDbEntity") '(100 . "AcDbXline") (cons 10 a) (cons 11 (unit (mapcar '- b a)))))
                      )
                      (setq xll (cons xl xll))
               )
             )
            plst
            (cdr (reverse (cons (car plst) (reverse plst))))
    )
    (foreach x xll
      (setq ip (vlax-curve-getclosestpointto x p))
      (setq ipp (cons ip ipp))
    )
    (setq dstl (mapcar '(lambda (x) (distance x p)) ipp))
    (foreach x xll
      (entdel x)
    )
    (eval (cons 'min (ListDupes dstl)))
  ) 

  (defun insidep (pt entn / big flag obj1 obj2 obj3 p1 p2 small)
    (if (and pt entn)
      (progn
        (setq obj1 (vlax-ename->vla-object entn))
        (setq obj2 (car (vlax-invoke obj1 'Offset 0.001))
              obj3 (car (vlax-invoke obj1 'Offset -0.001))
        )
        (if (> (vla-get-area obj2) (vla-get-area obj3))
          (progn
            (set 'big obj2)
            (set 'small obj3)
          )
          (progn
            (set 'big obj3)
            (set 'small obj2)
          )
        )
        (setq p1 (vlax-curve-getClosestPointTo big pt)
              p2 (vlax-curve-getClosestPointTo small pt)
        )
        (if (> (distance pt p1) (distance pt p2))
          (setq flag T)
          (setq flag nil)
        )
        (mapcar (function (lambda (x)
                            (progn
                              (vla-delete x)
                              (vlax-release-object x)
                            )
                          )
                )
                (list big small)
        )
      )
    )
    flag
  )

  (defun unique (lst)
    (if lst
      (cons (car lst)
            (unique (_vl-remove (car lst) (cdr lst) 1e-6))
      )
    )
  )

  (defun _vl-remove (el lst fuzz)
    (vl-remove-if
      '(lambda (x)
         (and (equal (car x) (car el) fuzz)
              (equal (cadr x) (cadr el) fuzz)
         )
       )
      lst
    )
  )

  (defun ridge (v1 v2)
    (if (not
          (minusp (- (* (car v1) (cadr v2)) (* (car v2) (cadr v1))))
        )
      (mapcar '*
              (list -1.0 -1.0 -1.0)
              (mapcar '- v1 v2)
      )
      (if (or (equal (- (* (car v1) (cadr v2)) (* (car v2) (cadr v1)))
                     0.0
                     1e-8
              )
              (equal (- (* (car v1) (cadr v2)) (* (car v2) (cadr v1)))
                     -0.0
                     -1e-8
              )
          )
        (if (equal v1 v2 1e-8)
          (polar '(0.0 0.0 0.0)
                 (+ (angle '(0.0 0.0 0.0) v1) (/ pi 2.0))
                 1.0
          )
          v2
        )
        (mapcar '- v1 v2)
      )
    )
  )

  (defun onlin-p (p1 p2 p)
    (and
      (equal (distance p1 p2)
             (+ (distance p1 p) (distance p2 p))
             1e-8
      )
      (not (equal p1 p 1e-8))
      (not (equal p2 p 1e-8))
    )
  )

  (defun assocon (SearchTerm Lst func fuzz)
    (car
      (vl-member-if
        (function
          (lambda (pair)
            (equal SearchTerm (apply func (list pair)) fuzz)
          )
        )
        lst
      )
    )
  )

  (defun prelst (lst el / f)
    (vl-remove-if
      '(lambda (a) (or f (setq f (equal a el 1e-8))))
      lst
    )
  )

  (defun suflst (lst el)
    (cdr (vl-member-if '(lambda (a) (equal a el 1e-8)) lst))
  )

  (defun unit (v)
    (mapcar '(lambda (x) (/ x (distance '(0.0 0.0 0.0) v))) v)
  )

  (setq
    vl (mapcar
         'cdr
         (vl-remove-if-not
           '(lambda (x) (= (car x) 10))
           (entget pol)
         )
       )
  )
  (setq vl (cons (last vl) vl))
  (setq tl (mapcar '(lambda (a b) (mapcar '- b a)) vl (cdr vl)))
  (setq tl (mapcar '(lambda (x) (unit x)) tl))
  (setq vtl (mapcar '(lambda (a b) (list a b)) vl tl))
  (setq rl (mapcar '(lambda (a b) (ridge a b))
                   tl
                   (cdr (reverse (cons (car tl) (reverse tl))))
           )
  )
  (setq rl (mapcar '(lambda (x) (unit x)) rl))
  (setq vrl (mapcar '(lambda (a b) (list a b))
                    (cdr (reverse (cons (car vl) (reverse vl))))
                    rl
            )
  )
  (setq vrl (cons (last vrl) (reverse (cdr (reverse vrl)))))
  (setq pln T)

  (defun kr (lst / pl vpx1 vpxp1 vpx2 vpxp2 pp vxx z)
    (mapcar
      '(lambda (a b)
         (setq p
                (inters (car a)
                        (mapcar '+ (car a) (cadr a))
                        (car b)
                        (mapcar '+ (car b) (cadr b))
                        nil
                )
         )
         (setq pl (cons p pl))
       )
      (reverse (cons (car lst) (reverse lst)))
      (cdr (reverse (cons (car lst) (reverse lst))))
    )
    (setq vpl (mapcar '(lambda (a b c) (list (list a b) (list c b)))
                      vl
                      (reverse pl)
                      (cdr (reverse (cons (car vl) (reverse vl))))
              )
    )
    (setq vpl (apply 'append vpl))
;    (while (assocon nil vpl 'cadr 1e-6)
;      (setq vpl (vl-remove (assocon nil vpl 'cadr 1e-6) vpl))
;    )
    (setq pln nil)
    (foreach p pl
      (if (vl-some
            '(lambda (x)
               (vl-catch-all-apply 'onlin-p (list (car x) (cadr x) p))
             )
            vpl
          )
        (setq pln (cons p pln))
      )
    )
    (setq pln (mapcar '(lambda (x) (if (insidep x pol) x)) pln))
    (setq pln (vl-remove nil pln))
    (setq pln
      (mapcar
       '(lambda (x)
          (if (valid-inscribed-circle-p x pol) x)
        )
       pln
      )
    )
    (setq pln (vl-remove nil pln))
    (setq vx nil)
    (foreach p pln
      (mapcar '(lambda (x)
                 (if (equal (cadr x) p 1e-6)
                   (setq vx (cons x vx))
                 )
               )
              vpl
      )
    )
    (if (and (not (= (length pln) 1)) vx)
      (progn
        (setq vx (vl-sort vx
                          '(lambda (a b)
                             (< (inscribed-circle (cadr a) pol)
                                (inscribed-circle (cadr b) pol)
                             )
                           )
                 )
        )
        (if (and plnz (equal (cadr plnz) (inscribed-circle (cadar vx) pol) 1e-6))
          (if (equal (cadar vx) (cadadr vx) 1e-8)
            (if (> (distance (car plnz) (cadar vx)) (distance (car plnz) (cadr (caddr vx))))
              (setq vx (cons (caddr vx) vx))
            )
            (if (> (distance (car plnz) (cadar vx)) (distance (car plnz) (cadadr vx)))
              (setq vx (cons (cadr vx) vx))
            )
          )
        )
        (setq pln (list (cadar vx)))
      )
    )
    (if (null vx)
      (setq pln nil)
    )
    (if (vl-every '(lambda (x) (equal (cadar vpl) (cadr x) 1e-6))
                  vpl
        )
      (if (and (vl-every '(lambda (x) (eq (cadr x) nil)) vpl)
               (eq (length (unique vpl)) 2)
          )
        (progn
          (setq z  (entmakex (list '(0 . "LINE")
                                   (cons 10 (caar (unique vpl)))
                                   (cons 11 (caadr (unique vpl)))
                             )
                   )
                zz (cons z zz)
          )
          (setq pln nil)
        )
        (progn
          (foreach l (unique vpl)
            (setq z  (entmakex (list '(0 . "LINE")
                                     (cons 10 (car l))
                                     (cons 11 (cadr l))
                               )
                     )
                  zz (cons z zz)
            )
          )
          (setq pln nil)
        )
      )
    )
    (if (equal pln (list nil))
      (setq pln nil)
    )
    (if pln (setq plnz (list (car pln) (inscribed-circle (car pln) pol))))
    (foreach p pln
      (setq vp1 (cons (assocon p vpl 'cadr 1e-6) vp1))
      (setq vp2 (cons (assocon p (cdr (member (car vp1) vpl)) 'cadr 1e-6) vp2))
      (if (car vp1)
        (setq z  (entmakex (list '(0 . "LINE")
                                 (cons 10 (caar vp1))
                                 (cons 11 (cadar vp1))
                           )
                 )
              zz (cons z zz)
        )
      )
      (if (car vp2)
        (setq z  (entmakex (list '(0 . "LINE")
                                 (cons 10 (caar vp2))
                                 (cons 11 (cadar vp2))
                           )
                 )
              zz (cons z zz)
        )
      )
      (setq vpp2 (caar vp2))
      (setq v2 nil)
      (while (setq vpp2 (car (assocon vpp2 vp2 'cadr 1e-6)))
        (if (not (null vpp2))
          (setq v2 vpp2)
        )
      )
      (if (null v2)
        (setq v2 (caar vp2))
      )
      (setq vpp1 (caar vp1))
      (setq v1 nil)
      (while (setq vpp1 (car (assocon vpp1 vp1 'cadr 1e-6)))
        (if (not (null vpp1))
          (setq v1 vpp1)
        )
      )
      (if (null v1)
        (setq v1 (caar vp1))
      )
      (setq pp
             (list
               p
               (unit
                 (ridge
                   (if
                     (cadr
                       (last (prelst vtl (assocon v1 vtl 'car 1e-6)))
                     )
                      (cadr
                        (last (prelst vtl (assocon v1 vtl 'car 1e-6)))
                      )
                      (cadr (last vtl))
                   )
                   (cadr (assocon v2 vtl 'car 1e-6))
                 )
               )
             )
      )
      (setq vrl (if vrl
                  (subst pp (assocon (caar vp1) vrl 'car 1e-6) vrl)
                  (subst pp (assocon (caar vp1) lst 'car 1e-6) lst)
                )
            vrl (if (assocon (caar vp2) vrl 'car 1e-6)
                  (subst pp (assocon (caar vp2) vrl 'car 1e-6) vrl)
                )
      )
      (setq vl (subst p (caar vp1) vl)
            vl (subst p (caar vp2) vl)
      )
    )
  )

  (while pln (kr vrl))
)

(defun c:2droof-MR (/ *error* adoc plnz)

  (vl-load-com)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))

  (defun *error* (msg)
    (if plnz
      (setq plnz nil)
    )
    (if zz
      (setq zz nil)
    )
    (if poly
      (setq poly nil)
    )
    (vla-endundomark adoc)
    (if msg
      (prompt msg)
    )
    (princ)
  )

  (vla-startundomark adoc)

  (setq poly
         (car
           (entsel
             "\nPick closed LWPOLYLINE in WCS oriented CCW and with only straight segments-edges"
           )
         )
  )

  (2droof poly)

  (*error* nil)

  (princ)
)
« Last Edit: February 11, 2014, 09:44:56 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

chlh_jd

  • Guest
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #65 on: February 11, 2014, 09:48:43 AM »
Which One is right ?

The one on the left
Thanks Tim ! Sorry for reviting it too later .
The one on the right has a "Dead Vally" (a flat valley). This is to be avoided but sometime can not.
When you can't get away from the situation you add a "Cricket"  8-)
Alan,thank you too !  Sorry for reviting it too later .

---------------------------------------------------------------------------------
I think for this problem it can be solved by three way :
1. Offset method , just like here suggest : "Straight Skeletons for Roofs"  http://www.theswamp.org/index.php?topic=721.0
2. Construction 3d inwardly inclined plane, and get it's cast sight .
3. Use of physical methods, the film filled with water will form all fall ridge lines ; Or Eq Strong trace of the edge gravitational field .

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #66 on: February 11, 2014, 11:21:10 AM »
Which One is right ?

The one on the left

Here is an interesting example... According to my routine-last posted one and GP's it seems that both soultion is correct, but in reality I would use right one, because of death valley and I would 2 parallel and close ridges implement as one...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #67 on: February 11, 2014, 11:29:08 AM »
Garry's is closest but not quite.
This is correct.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

snownut2

  • Swamp Rat
  • Posts: 971
  • Bricscad 22 Ultimate
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #68 on: February 11, 2014, 11:32:14 AM »
CAB,

Is correct, not sure if its the resolution but there appears to be a little jog in the ridge.  Also much easier to construct, than the death valley version.

LE3

  • Guest
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #69 on: February 11, 2014, 11:48:19 AM »
Was curios, and end up rebuilding my old skeletonsRoof arx class for a2014, and I get this (see image):

GP

  • Newt
  • Posts: 83
  • Vercelli, Italy
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #70 on: February 11, 2014, 11:54:34 AM »
Which is correct?

The valleys must be sloped and start from the lower roof edge.


CAB,

Is correct, not sure if its the resolution but there appears to be a little jog in the ridge...

Yes, see posted dwg.

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #71 on: February 15, 2014, 02:42:43 PM »
Now there are no dead valleys... Both solutions are correct... If you don't believe, use my 2droof3d.lsp and check it in 3D... One on the left was made by my last 2droof-MR.lsp and one on the right by GP's HR.lsp... So now we stand for solution - which one do you like it more?

Regards, M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #72 on: February 17, 2014, 04:54:41 AM »
Another update of 2droof3d.lsp... You can find it here :

http://www.theswamp.org/index.php?topic=41837.msg513241#msg513241

Sorry for inconvenience... There was mistake in my subfunction ListClockwise-p which I fixed - the code was actually the same as old one - only this fix and now this is new version...

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

chlh_jd

  • Guest
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #73 on: February 22, 2014, 12:50:17 AM »
Now there are no dead valleys... Both solutions are correct... If you don't believe, use my 2droof3d.lsp and check it in 3D... One on the left was made by my last 2droof-MR.lsp and one on the right by GP's HR.lsp... So now we stand for solution - which one do you like it more?

Regards, M.R.
I think the right is right . In MidLine ABC, |AB|<|AC|;it can be deduced by Offset-method , Outline offset to Point C will be continued, but offset to Point B will be break .

chlh_jd

  • Guest
Re: ==={Challenge}===Find the ridge lines of sloped roof
« Reply #74 on: February 22, 2014, 01:08:14 AM »
Another update of 2droof3d.lsp... You can find it here :

http://www.theswamp.org/index.php?topic=41837.msg513241#msg513241

Sorry for inconvenience... There was mistake in my subfunction ListClockwise-p which I fixed - the code was actually the same as old one - only this fix and now this is new version...

M.R.
I test your "2droof3d new old lisp" , it can't run well in my ACAD2011 , See the test Gif .