9 Replies Latest reply on Dec 13, 2011 4:45 AM by Harbs.

    [JS CS5.5] How to get the constructor name of an oval?

    KeithGilbert Level 1

      I have a mix of rectangles and ovals on the page. The rectangles of course return the constructor.name of "Rectangle". Ovals that were drawn with the Ellipse tool return the constructor.name of "Oval". But a rectangle that has been converted to an oval via Object > Convert Shape still returns the constructor.name "Rectangle". Is there any way around this?

       

      What I need to do is output the vertices of all the rectangles and polygons on the page (which I have working now), and also some sort of meaningful representation of the ovals, such as center point and diameter. I see 2 problems:

       

      1. I can't tell an oval from a rectangle because of what I describe in my first paragraph above

       

      2. Once I determine it is an oval, it appears the only data I can get from it is paths[0].entirePath. I'm sure there is a way to matematically reduce this path data to a simple center point/diameter combination, but it looks tricky. Has anyone done this, or is there another way?

       

      Thanks for any tips anyone can share!

        • 1. Re: [JS CS5.5] How to get the constructor name of an oval?
          [Jongware] Most Valuable Participant

          1. Weird, it works as expected in CS4. An Improvement due to Customer Request? It seems a lot of these popped up recently.

           

          2. 'entirePath' is a simple array with one element per vertex. Each vertex is one of these: [x,y] or [x,y, left-direction x,y, right-direction x,y] -- but you don't need to know whether the vertices are curved or not, you can simply use the first two items.

           

          The center is at [ (paths[0].entirePath[0][0]+paths[0].entirePath[2][0])/2, (paths[0].entirePath[0][1]+paths[0].entirePath[2][1])/2 ] -- using just two random points, you can also add up all of the x's and y's and divide by the length of entirePath in case the oval is rotated.

           

          For its diameter, you can subtract right vertex from left vertex or bottom vertex from top vertex -- either one in case of a certified circle.

           

          ... Just typed all of this and now I realize you can simply use geometricBounds -- if the ellipse may be rotated, you have to look into Math 1-0-1 to un-rotate the values, although the center will still be the same.

          1 person found this helpful
          • 2. Re: [JS CS5.5] How to get the constructor name of an oval?
            Marc Autret Level 4

            Hey, that's Schrödinger's cat!

             

            Sometimes a rectangle converted into an oval is considered a Rectangle, sometimes it is considered an Oval. Playing with undo / redo I even found that the same object can be said "rectangle" or "oval"—this seems totally unpredictable.

             

            To me this is a bug and should be filed as such. After several tries I haven't be able to reproduce the issue in InDesign CS4, but it obviously occurs in both CS5 and CS5.5. Create a new rectangle, apply "convert shape to an ellipse" and check app.selection[0].__class__. Rectangle? Oval? Try again with another rectangle, unselect/reselect the item, play with undo/redo, etc.

             

            I'm not sure if it's a good idea to find a hack, but here's an attempt:

             

             

            function isOval(/*PageItem*/o)
            //--------------------------------------
            // Returns TRUE if o is 'actually' an oval
            // despite wrong cast -- Hack for ID CS5+
            {
                var t, r;
            
                if( o instanceof Oval ) return true;
            
                if( (t=o.paths).length > 1 ) return false;
            
                t = ''+t[0].entirePath;
            
                o.convertShape(ConvertShapeOptions.CONVERT_TO_OVAL);
                r = t==(''+o.paths[0].entirePath);
            
                t = o.toSpecifier();
                resolve(t.substr(0,t.indexOf('//'))).undo();
            
                return r;
            }
            
            // Sample code:
            alert( isOval(app.selection[0]) );
            

             

            Hope that helps.

             

            @+

            Marc

            1 person found this helpful
            • 3. Re: [JS CS5.5] How to get the constructor name of an oval?
              KeithGilbert Level 1

              Thanks to both of you Jongware and Marc! Your answers were really helpful. The "Hack" you put together Marc works great for this use case.

               

              FWIW, I experimented this morning with trying to get the object name as it appears in the Layers panel. That was tantalizing because the layers panel displays "<circle>" "<oval>","<rectangle>" accurately. But object.name returns nothing unless you've actually modified the name in the layers panel. Frustrating.

               

              I assume the buggy behavior of constructor.name in CS5 is related to this new layers panel naming behavior in CS5. Ah well, 2 steps forward, 1 step back!

              • 4. Re: [JS CS5.5] How to get the constructor name of an oval?
                Harbs. Level 6

                I have not played with your specific issue, but...

                 

                In my experience you can get reliable results on the true constructor using:

                 

                obj.getElements()[0].constructor

                 

                getElements() forces InDesign to resolve the object to what it truly is...

                 

                HTH,

                Harbs

                 

                [Edit] You need getElements()[0] because getElements() always returns an array -- even when it's used on a single non-composite object...

                • 5. Re: [JS CS5.5] How to get the constructor name of an oval?
                  Harbs. Level 6

                  I'm not sure whether this is a true bug, or a side-effect of performance tradeoffs

                   

                  Depending on how you access objects, InDesign does not always parse an object for its full type information, and probably uses cached data as much as possible.

                   

                  If you need fully qualified objects you should always use getElements()...

                   

                  Harbs

                  • 6. Re: [JS CS5.5] How to get the constructor name of an oval?
                    Harbs. Level 6

                    In your case, you'd probably want to do something like this:

                     

                    var myObjs = myPage.pageItems.everyItem().getElements();

                    This should return an array of fully qualified objects.

                     

                    Harbs

                    • 7. Re: [JS CS5.5] How to get the constructor name of an oval?
                      Marc Autret Level 4

                      Hi Harbs,

                       

                      I fully understand your argument. When Keith posted his question my first impulse was to check around for unresolved objects and so on. But the fact is this is not a getElements()-issue, as evidenced by the following screenshot:

                       

                      Oval-BUG.png

                      As mentioned, this error is not systematic. Sometimes the converted Rectangle is properly recognized as an Oval, but occasionally we get the result above.

                       

                      > Depending on how you access objects, InDesign does not always parse an object

                      > for its full type information, and probably uses cached data as much as possible.

                       

                      Yes, but it seems we can not rely on the update of the cache even with fully qualified objects. (Once again, I could not produce this error in ID CS4.)

                       

                      @+

                      Marc

                      • 8. Re: [JS CS5.5] How to get the constructor name of an oval?
                        Marc Autret Level 4

                        In addition,  I get the bug in a systematic way if I use the following code:

                         

                         

                        var doc = app.activeDocument,
                            obj = doc.rectangles.add(),
                            objId = obj.id;
                        
                        obj.convertShape(ConvertShapeOptions.CONVERT_TO_OVAL);
                        
                        alert([
                            "Rectangles: " +
                                doc.rectangles.length,
                            "Ovals: " +
                                doc.ovals.length,
                            "Current object: " +
                                doc.pageItems.itemByID(objId).getElements()[0].constructor.name
                            ].join('\r'));
                        
                        // CS4 =>
                        //   Rectangles: 0
                        //   Ovals: 1
                        //   Current object: Oval
                        
                        // CS5+ =>
                        //   Rectangles: 1
                        //   Ovals: 0
                        //   Current object: Rectangle
                        

                         

                        @+

                        Marc

                        • 9. Re: [JS CS5.5] How to get the constructor name of an oval?
                          Harbs. Level 6

                          Oh. Okay.

                           

                          Looks like a bug to me...

                           

                          Harbs