Application d'aide à  la conception de parapente

Bonjour à  tous,

suite à  nos premiers échanges et présentations, je vous propose mon projet d'application.



L'objectif principal de l'application en question est d'aider à  la conception de parapentes.



Jusqu'à  maintenant je définissais des paramètres de conceptions dans une feuille excel pour ensuite construire le modèle 3D avec Rhino Mac (beta). Mise à  plat des surfaces tirées avec Rhino et impression sur plan, possiblement directement sur rouleau de tissu.



L'appli devrait au moins se substituer à  la feuille excel et permettre d'étudier de nombreuses conceptions différentes et effectuer une étude paramétrique du comportement de l'aile. L'analyse numérique (étude aérodynamique) n'est pas une priorité pour le moment mais serait souhaitable à  terme.



Quoiqu'il en soit, un parapente n'est qu'un assemblage cousu de panneaux de tissu, quelques joncs, renforts, pattes d'ancrage, suspentes, etc. L'appli devra fournir le minimum de données nécessaires à  la construction de ces éléments avec Rhino et au mieux rendre le modèle en 3D puis mettre à  plat les panneaux.



J'ai déjà  un peu travaillé sur une façon de dessiner la forme à  plat et la voûte de l'aile, au sein de NSView, avec des NSPoint et NSBezierPath. Il est temps de construire un Modèle complet et robuste, accompagné de vues et contrôleurs, mais je ne parviens pas à  mettre en oeuvre une méthode MVC.



Avez-vous des conseils pour l'élaboration de mon modèle?



Remarque : je travaille avec XCode 3.4 (de mémoire) sous Snow Leopard (à  jour).



En prime : une copie d'écran de l'appli au stade embryonnaire...
«1

Réponses

  • Ce sujet ayant peu de succes, je reformule une question plus ciblee. Merci de me rediriger vers un sujet existant que je n'aurais pas trouve..



    Comment developper un projet de type MVC qui puisse correspondre a mon projet d'appli mac os x?

    Peut etre un tutoriel sur la methode avec le code de base?

    Je suis debutant et encore peu familier de l'objective C mais je me debrouille avec les vues. Je ne parviens pas a transposer les exemple de MVC et NSTableView a quelque chose de plus general quitte a la jouer plus en "manuel".

    Une bonne piste serait la bienvenue.

    Merci pour vos reponses
  • CéroceCéroce Membre, Modérateur
    janvier 2013 modifié #3
    En préambule, et pour résumer ce n'est pas une question simple.



    L'idée du MVC c'est que les données métier (le Modèle) sont séparées de leur représentation (la vue).

    Pour l'instant, tu as travaillé sur la vue. Ainsi, quand on dessine une aile, on place des points avec des coordonnées vue.



    Je pense que tu as compris que dans le modèle, on va parler de coordonnées physiques. Ainsi, on peut considérer qu'on y parle en mètres.



    Voici comment je m'y prendrais.



    Modèle



    Point



    Déjà , je crée un type synonyme de double, pour indiquer des longueurs physiques:


    typedef double PhysicalLength;
    




    Je peux alors définir un point. On pourrait utiliser une structure:


    <br />
    typedef struct {<br />
    	PhysicalLength x;<br />
    	PhysicalLength y;<br />
    	PhysicalLength z;<br />
    } PhysicalPoint ;
    




    mais, je crois que ce n'est pas judicieux, parce que typiquement, on voudra modifier les coordonnées du point en tapant dans un champ, et il vaut donc mieux utiliser une classe:


    <br />
    @interface PhysicalPoint:NSObject<br />
    <br />
    @property (assign) PhysicalLength x;<br />
    @property (assign) PhysicalLength y;<br />
    @property (assign) PhysicalLength z;<br />
    <br />
    @end
    






    Sommet



    Je définis un Sommet comme l'association d'un point d'ancrage et de deux points de contrôle:


    <br />
    @interface PhysicalVertex:NSObject<br />
    <br />
    @property (strong) PhysicalPoint anchor;<br />
    @property (strong) PhysicalPoint control0;<br />
    @property (strong) PhysicalPoint control1;<br />
    <br />
    @end
    






    Voile



    Une voile est décrite par une liste de sommets:


    <br />
    @interface Sail:NSObject<br />
    <br />
    @property (strong) NSMutableArray *vertices; // Liste de PhysicalVertex.<br />
    <br />
    @end
    




    Tu n'oublieras évidemment pas d'instancier vertices dans -init.





    Vue



    Pour les vues, le plus simple est qu'elles prennent directement la liste des sommets en entrée.

    Pour la vue de face:


    <br />
    @interface FrontSailView:NSView<br />
    <br />
    @property (nonatomic, strong) NSMutableArray *vertices;<br />
    <br />
    @end
    




    Pareil pour la vue de haut. Ce sont les mêmes sommets:


    <br />
    @interface TopSailView:NSView<br />
    <br />
    @property (nonatomic, strong) NSMutableArray *vertices;<br />
    <br />
    @end
    




    Pour le reste, tu l'as déjà  fait en grande partie: il faut de projeter les sommets et de dessiner le tout avec un NSBezierPath. Evidemment, tu auras des problèmes d'échelle, à  toi de jouer.





    Contrôleur



    Il est de fait très simple: il va instancier une voile, alors il devra conserver une référence dessus. Il possède aussi des outlets vers les deux vues:


    <br />
    @interface SailEditorViewController:NSViewController<br />
    <br />
    @property (nonatomic, strong) Sail *sail;<br />
    @property (nonatomic, weak) IBOutlet FrontSailView *frontView;<br />
    @property (nonatomic, weak) IBOutlet TopSailView *topView;<br />
    <br />
    @end
    




    J'ai utilisé un NSViewController, mais ça peut être un NSWindowController.





    Il lui faudra créer une voile (par exemple, dans sa méthode initWithNibName...,)



    Lorsque les vues sont prêtes, dans la méthode -awakeFromNib, il faudra alors passer la voile aux deux vues:


    <br />
    - (void) awakeFromNib<br />
    {<br />
    	// Pour simplifier, je fais l&#39;instanciation du modèle ici:<br />
       self.sail = [[Sail alloc] init];<br />
    <br />
       // On passe directement le Modèle à  la Vue. ça va, parce que la représentation interne des sommets doit être la même:<br />
       self.frontView.vertices = self.sail.vertices;<br />
       self.topView.vertices = self.sail.vertices;<br />
    }
    




    Voilà , ça devrait être un bon début.
  • Merci pour ta reponse, qui devrait etre un bon point de depart en effet. Je vais m'y pencher!
  • AirdrienAirdrien Membre
    janvier 2013 modifié #5
    Il doit me manquer certaines étapes, cela ne fonctionne pas.

    Voici mon code :



    MODELE :
    <br />
    // PhysicalPoint.m<br />
    #import &quot;PhysicalPoint.h&quot;<br />
    @implementation PhysicalPoint<br />
    @synthesize x, y, z;<br />
    @end<br />
    



    <br />
    // PhysicalPoint.h<br />
    #import &lt;cocoa cocoa.h=&quot;&quot;&gt;<br />
    @interface PhysicalPoint:NSObject {<br />
    }<br />
    @property (assign) double x;<br />
    @property (assign) double y;<br />
    @property (assign) double z;<br />
    @end<br />
    



    <br />
    //  Vault.h<br />
    #import &lt;cocoa cocoa.h=&quot;&quot;&gt;<br />
    @interface Vault : NSObject<br />
    @property (assign) NSMutableArray *points;<br />
    @end<br />
    

    <br />
    //  Vault.m<br />
    #import &quot;Vault.h&quot;<br />
    #include &quot;PhysicalPoint.h&quot;<br />
    @implementation Vault<br />
    @synthesize points = _points;<br />
    -(id)init<br />
    {<br />
    self.points = [[NSMutableArray alloc] init];<br />
    PhysicalPoint *point;<br />
    point.x = 425;<br />
    point.y = 375;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    point.x = 650;<br />
    point.y = 325;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    point.x = 725;<br />
    point.y = 210;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    point.x = 510;<br />
    point.y = 375;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    point.x = 595;<br />
    point.y = 355;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    point.x = 705;<br />
    point.y = 295;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    point.x = 735;<br />
    point.y = 250;<br />
    point.z = 0;<br />
    [self.points addObject:point];<br />
    return self;<br />
    }<br />
    <br />
    @end<br />
    


    Cette init est un test, les coordonnées devraient donner une belle forme, mais sans réalité métrique pour l'instant.


    <br />
    //  VaultShapeView.h<br />
    #import &lt;cocoa cocoa.h=&quot;&quot;&gt;<br />
    <br />
    @interface VaultShapeView : NSView {<br />
    <br />
    IBOutlet NSTextField *flatteningTextField;<br />
    IBOutlet NSButton *controlPointsCheck;<br />
    <br />
    NSBezierPath *vaultPath;<br />
    NSBezierPath *controlPath;<br />
    <br />
    NSPoint vaultPoints [3];<br />
    NSPoint controlPoints [4];<br />
    <br />
    }<br />
    @property (assign) NSMutableArray *points;<br />
    <br />
    - (IBAction)generateVaultShape:(id)sender;<br />
    - (IBAction)resetView:(id)sender;<br />
    - (IBAction)needsDisplayControl:(id)sender;<br />
    - (void)standardView;<br />
    - (void)createPath;<br />
    <br />
    @end<br />
    


    C'est ma custom view qui fonctionne en autonomie, avant le passage en MVC


    <br />
    //  VaultShapeView.m<br />
    #import &quot;VaultShapeView.h&quot;<br />
    #include &quot;PhysicalPoint.h&quot;<br />
    NSPoint downLocation, currentLocation;<br />
    NSInteger controlPointIndex;<br />
    NSInteger shapePointIndex;<br />
    @implementation VaultShapeView<br />
    @synthesize points;<br />
    - (id)initWithFrame:(NSRect)frame {<br />
        self = [super initWithFrame:frame];<br />
        if (self) {<br />
    	    // Initialization code here.<br />
      vaultPath = [[NSBezierPath alloc] init];<br />
      controlPath = [[NSBezierPath alloc] init];<br />
        }<br />
        return self;<br />
    }<br />
    -(IBAction)generateVaultShape:(id)sender<br />
    {<br />
    /*<br />
    vaultPoints [0] = NSMakePoint(425, 375);<br />
    vaultPoints [1] = NSMakePoint(650, 325);<br />
    vaultPoints [2] = NSMakePoint(725, 210);<br />
    <br />
    controlPoints [0] = NSMakePoint(510, 375);<br />
    controlPoints [1] = NSMakePoint(595, 355);<br />
    controlPoints [2] = NSMakePoint(705, 295);<br />
    controlPoints [3] = NSMakePoint(735, 250);<br />
      */<br />
    PhysicalPoint *point;<br />
    for (int i = 0;i&lt;3;i++)<br />
    {<br />
      point = [self.points objectAtIndex:i];<br />
      vaultPoints [i] = NSMakePoint(point.x, point.y);<br />
      NSLog(@&quot;point%d x=%f y=%f&quot;,i,point.x,point.y);<br />
    }<br />
    for (int i = 0;i&lt;4;i++)<br />
    {<br />
      point = [self.points objectAtIndex:(i+3)];<br />
      controlPoints [i] = NSMakePoint(point.x, point.y);<br />
    }<br />
    /*vaultPoints [1] = NSMakePoint(points[1].x, points[1].y);<br />
    vaultPoints [2] = NSMakePoint(points[2].x, points[2].y);<br />
    <br />
    controlPoints [0] = NSMakePoint(points[3].x, points[3].y);<br />
    controlPoints [1] = NSMakePoint(points[4].x, points[4].y);<br />
    controlPoints [2] = NSMakePoint(points[5].x, points[5].y);<br />
    controlPoints [3] = NSMakePoint(points[6].x, points[6].y);<br />
      */<br />
    <br />
    <br />
    [self createPath];<br />
    [self standardView];<br />
    }<br />
    - (void)createPath<br />
    {<br />
    [vaultPath removeAllPoints];<br />
    [controlPath removeAllPoints];<br />
    <br />
    [vaultPath moveToPoint:vaultPoints[0]];<br />
    [vaultPath curveToPoint:vaultPoints[1] controlPoint1:controlPoints[0] controlPoint2:controlPoints[1]];<br />
    [vaultPath curveToPoint:vaultPoints[2] controlPoint1:controlPoints[2] controlPoint2:controlPoints[3]];<br />
    [controlPath moveToPoint:vaultPoints[0]];<br />
    [controlPath lineToPoint:controlPoints[0]];<br />
    <br />
    [controlPath moveToPoint:controlPoints[1]];<br />
    [controlPath lineToPoint:controlPoints[2]];<br />
    <br />
    [controlPath moveToPoint:controlPoints[3]];<br />
    [controlPath lineToPoint:vaultPoints[2]];<br />
    <br />
    NSBezierPath *fPath = [vaultPath copy];<br />
    <br />
    NSAffineTransform *transform1 = [NSAffineTransform transform];<br />
    [transform1 translateXBy:(-[vaultPath bounds].origin.x) yBy:(-[vaultPath bounds].origin.x)];<br />
    [fPath transformUsingAffineTransform: transform1];<br />
    NSAffineTransform *transform2 = [NSAffineTransform transform];<br />
    [transform2 scaleXBy:-1 yBy:1];<br />
    [fPath transformUsingAffineTransform: transform2];<br />
    [transform1 invert];<br />
    [fPath transformUsingAffineTransform: transform1];<br />
    <br />
    [vaultPath appendBezierPath:fPath];<br />
    }<br />
    - (void)standardView<br />
    {<br />
    <br />
    NSRect viewBounds = [self bounds];<br />
    NSRect pathBounds = [vaultPath controlPointBounds];<br />
    <br />
    float arPath = pathBounds.size.width/pathBounds.size.height;<br />
    float arView = (viewBounds.size.width-40)/(viewBounds.size.height-40);<br />
    float scaleFactor, dX, dY;<br />
    <br />
    if (arPath &gt; arView)<br />
    {<br />
      scaleFactor = (viewBounds.size.width - 40) / pathBounds.size.width;<br />
      dX = 0;<br />
      dY = 0.5*((viewBounds.size.height - 40) - (pathBounds.size.height * scaleFactor));<br />
    }<br />
    else <br />
    {<br />
      scaleFactor = (viewBounds.size.height - 40) / pathBounds.size.height;<br />
      dX = 0.5*((viewBounds.size.width-40) - (pathBounds.size.width * scaleFactor));<br />
      dY = 0;<br />
    }<br />
    for (NSInteger i=0; i&lt;3 ; i++)<br />
    {<br />
      vaultPoints[i].x = (vaultPoints[i].x - pathBounds.origin.x) * scaleFactor + 20 + dX;<br />
      vaultPoints[i].y = (vaultPoints[i].y - pathBounds.origin.y) * scaleFactor + 20 + dY;<br />
    }<br />
    for (NSInteger i=0; i&lt;4 ; i++)<br />
    {<br />
      controlPoints[i].x = (controlPoints[i].x - pathBounds.origin.x) * scaleFactor + 20 + dX;<br />
      controlPoints[i].y = (controlPoints[i].y - pathBounds.origin.y) * scaleFactor + 20 + dY;<br />
    }<br />
    <br />
    [self createPath];<br />
    [self setNeedsDisplay:YES];<br />
    }<br />
    - (IBAction)needsDisplayControl:(id)sender<br />
    {<br />
    [self createPath];<br />
    [self setNeedsDisplay:YES];<br />
    }<br />
    - (IBAction)resetView:(id)sender<br />
    {<br />
    [self standardView];<br />
    }<br />
    - (void)drawRect:(NSRect)dirtyRect<br />
    {<br />
        // Drawing code here.<br />
    NSRect viewBounds = [self bounds];<br />
    [[NSColor whiteColor] set];<br />
    [NSBezierPath fillRect:viewBounds];<br />
    [[NSColor blackColor] set];<br />
    [NSBezierPath strokeRect:viewBounds];<br />
    <br />
    <br />
    if(&#33;[vaultPath isEmpty])<br />
    {<br />
      [[NSColor darkGrayColor] set];<br />
      [vaultPath setLineWidth:4];<br />
      [vaultPath stroke];<br />
    <br />
      if ([controlPointsCheck state] == NSOnState) {<br />
    <br />
       NSRect symetryAxis;<br />
       symetryAxis.origin.x = vaultPoints[0].x;<br />
       symetryAxis.origin.y = vaultPoints[2].y - 20;<br />
       symetryAxis.size.width = 0;<br />
       symetryAxis.size.height = vaultPoints[0].y - vaultPoints[2].y + 40;<br />
       [[NSColor greenColor] set];<br />
       [NSBezierPath strokeRect:symetryAxis];<br />
    <br />
       [[NSColor redColor] set];<br />
       [controlPath setLineWidth:1];<br />
       [controlPath stroke];<br />
    <br />
       for (int i = 0;i&lt;3;i++)<br />
       {<br />
        NSRect pointRect;<br />
        float rectSize = 8;<br />
        pointRect.origin.x = vaultPoints[i].x - rectSize/2;<br />
        pointRect.origin.y = vaultPoints[i].y - rectSize/2;<br />
        pointRect.size.width = rectSize;<br />
        pointRect.size.height = rectSize;<br />
        [[NSColor greenColor] set];<br />
        [NSBezierPath strokeRect:pointRect];<br />
       }<br />
    <br />
       for (int i = 0; i&lt;4; i++)<br />
       {<br />
        NSRect pointRect;<br />
        float rectSize = 4;<br />
        pointRect.origin.x = controlPoints[i].x - rectSize/2;<br />
        pointRect.origin.y = controlPoints[i].y - rectSize/2;<br />
        pointRect.size.width = rectSize;<br />
        pointRect.size.height = rectSize;<br />
        [[NSColor redColor] set];<br />
        [NSBezierPath fillRect:pointRect];<br />
       }<br />
      }<br />
    }<br />
    }<br />
    - (void)scrollWheel:(NSEvent *)theEvent<br />
    {<br />
    NSPoint center = [self convertPoint :[theEvent locationInWindow] fromView:nil];<br />
    float zoomFactor = [theEvent deltaY]/10 + 1.0;<br />
    for (NSInteger i=0; i&lt;3 ; i++)<br />
    {<br />
      vaultPoints[i].x = center.x + (vaultPoints[i].x - center.x) * zoomFactor;<br />
      vaultPoints[i].y = center.y + (vaultPoints[i].y - center.y) * zoomFactor;<br />
    }<br />
    for (NSInteger i=0; i&lt;4 ; i++)<br />
    {<br />
      controlPoints[i].x = center.x + (controlPoints[i].x - center.x) * zoomFactor;<br />
      controlPoints[i].y = center.y + (controlPoints[i].y - center.y) * zoomFactor;<br />
    }<br />
    [self createPath];<br />
    [self setNeedsDisplay:YES];}<br />
    - (void)mouseDown:(NSEvent *)theEvent<br />
    {<br />
    downLocation = [theEvent locationInWindow];<br />
    <br />
    for (NSInteger i=0; i&lt;3 ; i++)<br />
    {<br />
      NSRect pointRect;<br />
      float rectSize = 8;<br />
      NSPoint point = [self convertPoint:vaultPoints[i] toView:nil];<br />
      pointRect.origin.x = point.x - rectSize/2;<br />
      pointRect.origin.y = point.y - rectSize/2;<br />
      pointRect.size.width = rectSize;<br />
      pointRect.size.height = rectSize;<br />
    <br />
      if (NSPointInRect(downLocation, pointRect))<br />
      {<br />
       shapePointIndex = i;<br />
       break;<br />
      }<br />
      else shapePointIndex = -1;<br />
    }<br />
    <br />
    for (NSInteger i=0; i&lt;4 ; i++)<br />
    {<br />
      NSRect pointRect;<br />
      float rectSize = 5;<br />
      NSPoint point = [self convertPoint:controlPoints[i] toView:nil];<br />
      pointRect.origin.x = point.x - rectSize/2;<br />
      pointRect.origin.y = point.y - rectSize/2;<br />
      pointRect.size.width = rectSize;<br />
      pointRect.size.height = rectSize;<br />
    <br />
      if (NSPointInRect(downLocation, pointRect))<br />
      {<br />
       controlPointIndex = i;<br />
       break;<br />
      }<br />
      else controlPointIndex = -1;<br />
    }<br />
    <br />
    <br />
    //[self setNeedsDisplay: YES];<br />
    }<br />
    - (void)mouseDragged:(NSEvent *)theEvent<br />
    {<br />
    currentLocation = [theEvent locationInWindow];<br />
    NSRect viewBounds = [self bounds];<br />
    viewBounds.origin = [self convertPoint:viewBounds.origin toView:nil];<br />
    <br />
    // Sinon deplacer le dessin dans la vue<br />
    // ... si la souris est dans la vue<br />
    <br />
    if (NSPointInRect(currentLocation,viewBounds))<br />
    {<br />
      float dx = currentLocation.x - downLocation.x;<br />
      float dy = currentLocation.y - downLocation.y;<br />
      float factor;<br />
      if (shapePointIndex &#33;= -1)<br />
      {<br />
       switch(shapePointIndex)<br />
       {<br />
        case 0:<br />
    	 vaultPoints[0].y += dy;<br />
    	 controlPoints[0].y += dy;<br />
    	 break;<br />
        case 1:<br />
    	 vaultPoints[1].x += dx;<br />
    	 vaultPoints[1].y += dy;<br />
    	 controlPoints[1].x += dx;<br />
    	 controlPoints[1].y += dy;<br />
    	 controlPoints[2].x += dx;<br />
    	 controlPoints[2].y += dy;<br />
    	 break;<br />
        case 2:<br />
    	 vaultPoints[2].x += dx;<br />
    	 vaultPoints[2].y += dy;<br />
    	 controlPoints[3].x += dx;<br />
    	 controlPoints[3].y += dy;<br />
       }<br />
    <br />
      }<br />
      else if (controlPointIndex &#33;= -1)<br />
      {<br />
       float dx = currentLocation.x - downLocation.x;<br />
       float dy = currentLocation.y - downLocation.y;<br />
       switch(controlPointIndex)<br />
       {<br />
        case 0:<br />
    	 controlPoints[0].x += dx;<br />
    	 break;<br />
        case 1:<br />
    	 if (controlPoints[2].y &#33;= controlPoints[1].y)<br />
    	  factor = (controlPoints[2].y - vaultPoints[1].y) / (controlPoints[1].y - vaultPoints[1].y);<br />
    	 else<br />
    	  factor = (controlPoints[2].x - vaultPoints[1].x) / (controlPoints[1].x - vaultPoints[1].x);<br />
    	 controlPoints[1].x += dx;<br />
    	 controlPoints[1].y += dy;<br />
    	 controlPoints[2].x += dx * factor;<br />
    	 controlPoints[2].y += dy * factor;<br />
    	 break;<br />
        case 2:<br />
    	 if (controlPoints[1].y &#33;= controlPoints[2].y)<br />
    	  factor = (controlPoints[1].y - vaultPoints[1].y) / (controlPoints[2].y - vaultPoints[1].y);<br />
    	 else<br />
    	  factor = (controlPoints[1].x - vaultPoints[1].x) / (controlPoints[2].x - vaultPoints[1].x);<br />
    	 controlPoints[2].x += dx;<br />
    	 controlPoints[2].y += dy;<br />
    	 controlPoints[1].x += dx * factor;<br />
    	 controlPoints[1].y += dy * factor;<br />
    	 break;<br />
        case 3:<br />
    	 controlPoints[3].x += dx;<br />
    	 controlPoints[3].y += dy;<br />
    	 break;<br />
       }<br />
    <br />
      }<br />
      else {<br />
    <br />
       NSAffineTransform *transform1 = [NSAffineTransform transform];<br />
       float dx = currentLocation.x - downLocation.x;<br />
       float dy = currentLocation.y - downLocation.y;<br />
       [transform1 translateXBy:dx yBy:dy];<br />
       for (NSInteger i=0; i&lt;3 ; i++)<br />
       {<br />
        vaultPoints[i].x += dx;<br />
        vaultPoints[i].y += dy;<br />
       }<br />
       for (NSInteger i=0; i&lt;4 ; i++)<br />
       {<br />
        controlPoints[i].x += dx;<br />
        controlPoints[i].y += dy;<br />
       }<br />
      }<br />
    }<br />
    downLocation = currentLocation;<br />
    [self createPath];<br />
    [self setNeedsDisplay:YES];<br />
    <br />
    }<br />
    - (void)mouseUp:(NSEvent *)theEvent<br />
    {<br />
    <br />
    for (NSInteger i=0; i&lt;3 ; i++)<br />
    {<br />
      NSLog(@&quot;vaultPoint%i : %f, %f&quot;,i,vaultPoints[i].x,vaultPoints[i].y);<br />
    }<br />
    <br />
    for (NSInteger i=0; i&lt;4 ; i++)<br />
    {<br />
      NSLog(@&quot;vaultPoint%i : %f, %f&quot;,i,controlPoints[i].x,controlPoints[i].y);<br />
    }<br />
    <br />
    <br />
    //[self setNeedsDisplay: YES];<br />
    }<br />
    <br />
    @end<br />
    


    OK là  c'est beaucoup de code inutile et surtout la manipulation du BezierPath avec les points est peu élégante, voire inapropriée si je veux modifier mon modèle à  la souris. Cela fonctionnait en autonomie avant MVC.


    <br />
    //  ParaViewController.h<br />
    #import &lt;cocoa cocoa.h=&quot;&quot;&gt;<br />
    #include &quot;Vault.h&quot;<br />
    #include &quot;VaultShapeView.h&quot;<br />
    @interface ParaViewController : NSViewController<br />
    @property (nonatomic, assign) Vault *vault;<br />
    @property (nonatomic, assign) IBOutlet VaultShapeView *VaultShapeView;<br />
    - (IBAction)generateVaultShape:(id)sender;<br />
    @end<br />
    



    <br />
    //  ParaViewController.m<br />
    #import &quot;ParaViewController.h&quot;<br />
    #include &quot;PhysicalPoint.h&quot;<br />
    @implementation ParaViewController<br />
    @synthesize vault = _vault;<br />
    @synthesize VaultShapeView = _vaultShapeView;<br />
    - (void) awakeFromNib<br />
    {<br />
    // Pour simplifier, je fais l&#39;instanciation du modèle ici:<br />
    NSLog(@&quot;bla&quot;);<br />
    // Si je laisse cet alloc + init, j&#39;ai un “EXC_BAD_ACCESS”.<br />
    self.vault = [[Vault alloc] init];<br />
    <br />
    // On passe directement le Modèle à  la Vue. ça va, parce que la représentation interne des &quot;points&quot; doit être la même:<br />
    self.VaultShapeView.points = self.vault.points;<br />
    }<br />
    -(IBAction)generateVaultShape:(id)sender<br />
    {<br />
    PhysicalPoint *point;<br />
    point.x = 425;<br />
    point.y = 375;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    point.x = 650;<br />
    point.y = 325;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    point.x = 725;<br />
    point.y = 210;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    point.x = 510;<br />
    point.y = 375;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    point.x = 595;<br />
    point.y = 355;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    point.x = 705;<br />
    point.y = 295;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    point.x = 735;<br />
    point.y = 250;<br />
    point.z = 0;<br />
    [self.vault.points addObject:point];<br />
    }<br />
    @end<br />
    




    Il doit y avoir pas mal de boulettes dans ce code...

    A minima je voudrais que mon appli s'ouvre et affiche le modèle "de base" que l'utilisateur pourra ensuite modifier.

    Pour rappel, je suis en Document Based app, je n'ai pas touché à  MyDocument.

    Dans IB j'ai ajouté mon View Controller et mis sa classe à  ParaViewController, lié l'IBOutlet VaultView à  ma custom view et l'IBAction generateVaultShape du contrôleur à  un bouton.

    Quand je clique ce bouton j'ai :

    2013-01-28 14:08:49.428 ParaApp[1301:a0f] -[NSButton setX:]: unrecognized selector sent to instance 0x10013ce80

    2013-01-28 14:08:49.429 ParaApp[1301:a0f] -[NSButton setX:]: unrecognized selector sent to instance 0x10013ce80





    Je présume que repartir de zéro serait judicieux, pour éclaircir ce code peu élégant, c'est pas un soucis, je préfère faire propre que continuer à  bidouiller en vain...

  • À quel endroit ça plante exactement ?

    Là , apparemment, tu essayes d'utiliser la méthode setX sur un NSButton qui ne la connaà®t pas...
  • AirdrienAirdrien Membre
    janvier 2013 modifié #7
    En fait ça plante pas vraiment, sauf dns awakeFromNib du controleur :
    [color=#880000]// Si je laisse cet alloc + init, j&#39;ai un “EXC_BAD_ACCESS”.[/color]<br />
    [color=#000088]self[/color][color=#666600].[/color][color=#000000]vault [/color][color=#666600]=[/color][color=#000000] [/color][color=#666600][[[/color][color=#660066]Vault[/color][color=#000000] alloc[/color][color=#666600]][/color][color=#000000] init[/color][color=#666600]];[/color]
    


    c'est surtout que mon modèle reste vide.

    Là  je tente avec NSLog de valider la méthode generateVaultShape sans succès. Cette méthode doit générer une forme standard. Mon controleur ressemble à  ca maintenant :
    <br />
    //<br />
    //  ParaViewController.m<br />
    //  ParaApp<br />
    //<br />
    //  Created by Adrien Lafite on 22/01/13.<br />
    //  Copyright 2013 __MyCompanyName__. All rights reserved.<br />
    //<br />
    #import &quot;ParaViewController.h&quot;<br />
    #include &quot;PhysicalPoint.h&quot;<br />
    @implementation ParaViewController<br />
    @synthesize vault = _vault;<br />
    @synthesize vaultShapeView;<br />
    -(IBAction)generateVaultShape<br />
    {<br />
    [self.vault.points removeAllObjects];<br />
    PhysicalPoint *point = [[PhysicalPoint alloc] init];<br />
    [point setX:425];<br />
    [point setY:375];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    [point setX:650];<br />
    [point setY:325];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    [point setX:725];<br />
    [point setY:210];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    [point setX:510];<br />
    [point setY:375];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    [point setX:595];<br />
    [point setY:355];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    [point setX:705];<br />
    [point setY:295];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    [point setX:735];<br />
    [point setY:250];<br />
    [point setZ:0];<br />
    [self.vault.points addObject:point];<br />
    <br />
    for (int i = 0;i&lt;7;i++)<br />
    {<br />
      PhysicalPoint *point = [self.vault.points objectAtIndex:i];<br />
      NSLog(@&quot;Point %d : x=%f y=%f z=%f&quot;,i,point.x,point.y,point.z);<br />
    }<br />
    <br />
    }<br />
    <br />
    - (void) awakeFromNib<br />
    {<br />
    // Pour simplifier, je fais l&#39;instanciation du modèle ici:<br />
    NSLog(@&quot;awakeFromNib&quot;);<br />
    //self.vault = [[Vault alloc] init];<br />
    [self generateVaultShape];<br />
    <br />
    <br />
    // On passe directement le Modèle à  la Vue. ça va, parce que la représentation interne des points doit être la même:<br />
    self.vaultShapeView.points = self.vault.points;<br />
    <br />
    }<br />
    <br />
    @end<br />
    




    Dans le log j'ai tout = 0.00000...
  • AirdrienAirdrien Membre
    janvier 2013 modifié #8
    Là , apparemment, tu essayes d'utiliser la méthode setX sur un NSButton qui ne la connaà®t pas...


    J'ai vu ça. Du coup j'ai enlevé l'action du bouton et transformé la méthode en -(void)generateVaultShape, appelée directement dans awakeFromNib.



    Je dois retourner bosser (jusqu'à  19h), dites moi si je fais fausse route. Merci pour votre aide (à  un débutant qui cafouille!) image/implore.gif' class='bbc_emoticon' alt=' o:) ' />
  • 'Airdrien' a écrit:


    J'ai vu ça. Du coup j'ai enlevé l'action du bouton et transformé la méthode en -(void)generateVaultShape, appelée directement dans awakeFromNib.



    Je dois retourner bosser (jusqu'à  19h), dites moi si je fais fausse route. Merci pour votre aide (à  un débutant qui cafouille!) image/implore.gif' class='bbc_emoticon' alt=' o:) ' />


    Je ne fais pas de développement sur Mac OSX, et je t'avouerais que j'ai un peu la flemme de lire tout ton code. J'ai juste regardé l'erreur de la console et dit ce que j'en pensais.
  • CéroceCéroce Membre, Modérateur
    janvier 2013 modifié #10
    Ton code est certainement simplifiable, il me semble que tu fais des traitements plusieurs fois. Je comprends que tu ne saisisses pas bien l'apport du MVC pour l'instant, mais considère quand même les points suivants:

    - si on entretient une synchro vue/modèle, déplacer un point horizontalement dans la vue de haut le déplace horizontalement dans le modèle. Donc, le déplace également horizontalement dans la vue de face.

    - en interne, on utilise des unités métriques, on pourrait donc, par exemple, fournir le fichier à  une machine de découpe.

    - on peut saisir les coordonnées d'un point directement en unités métriques.



    En l'état, ton code ne me semble pas si mal. Il y a des choses qui peuvent être simplifiées, mais c'est un bon début.


    <br />
    @property (assign) NSMutableArray *points;<br />
    


    J'ai pas écris ça. Intéresse-toi à  la gestion mémoire pour voir quelle est la différence entre (assign|weak|strong).

    ARC est-il activé dans ton projet ?



    Utilise le débogeur (mets des points d'arrêt dans la marre de gauche) pour vérifier l'état des variables, tu vas vite comprendre ce qui ne marche pas.



    Evite les chiffres dans ton code, du genre for(i=0; i<3; i++), on ne sait pas à  quoi correspond le 3. Et tu ne sauras plus non plus dans un mois.
    const NSUInteger ControlPoints = 3;
    
  • ARC est-il activé dans ton projet ?


    J'utilise XCode 3, pas d'ARC il me semble.

    A la place de strong je dois utiliser retain?

    Et pour weak, assign?
  • CéroceCéroce Membre, Modérateur
    janvier 2013 modifié #12
    'Airdrien' a écrit:


    J'utilise XCode 3, pas d'ARC il me semble.


    Exact. Ta machine est trop ancienne pour Xcode 4 ?


    'Airdrien' a écrit:


    A la place de strong je dois utiliser retain?


    Oui.


    'Airdrien' a écrit:


    Et pour weak, assign?


    Oui.



    Par contre, du coup, je ne sais pas pourquoi tu ne vois rien.
  • AirdrienAirdrien Membre
    janvier 2013 modifié #13
    Bien.



    J'ai un macbook core 2 duo 2.0 GHz, late 2006, je suis resté sous Snow Leopard. Lion tourne mais ça rame.



    A propos du contrôleur :
    Il lui faudra créer une voile (par exemple, dans sa méthode initWithNibName...,)


    Il faut écraser la méthode du contrôleur? Je l'ai pas fait.



    j'ai tout repris à  0 pour faire propre, mais j'ai une erreur dans awakefromnib avec alloc et init :
    <br />
    //<br />
    //  ParAppViewController.m<br />
    <br />
    #import &quot;ParAppViewController.h&quot;<br />
    @implementation ParAppViewController<br />
    @synthesize vaultShape, vaultShapeView;<br />
    <br />
    - (void) awakeFromNib<br />
    {<br />
    self.vaultShape = [[VaultShape alloc] init];<br />
    [self.vaultShape generateVaultShape];<br />
    self.vaultShapeView.vertices = self.vaultShape.vertices;<br />
    }<br />
    @end<br />
    




    2013-01-29 12:44:18.735 ParApp[4681:a0f] VaultShape:init

    Program received signal: “EXC_BAD_ACCESS”.
  • CéroceCéroce Membre, Modérateur
    'Airdrien' a écrit:


    Il faut écraser la méthode du contrôleur? Je l'ai pas fait.


    Tu as choisi un modèle Document-Based, et c'est très bien.

    Comme je ne le savais pas, je suis resté assez vague sur la classe du contrôleur, te parlant de NSViewController ou NSWindowController.



    Instancier le Modèle est le rôle du Contrôleur. Comme tu utilises l'architecture NSDocument, c'est ta sous-classe de NSDocument qui va l'instancier et qui va le retenir en mémoire:



    MyDocument.h:
    <br />
    @interface CEDocument : NSDocument<br />
    @property (nonatomic, retain) Vault* vault;<br />
    @end<br />
    






    MyDocument.m:
    <br />
    @implementation CEDocument<br />
    @synthesize vault = _vault;<br />
    - (id)init<br />
    {<br />
        self = [super init];<br />
        if (self) {<br />
    	    _vault = [[Vault alloc] init];<br />
        }<br />
        return self;<br />
    }<br />
    - (void) dealloc<br />
    {<br />
        [_vault release];<br />
       <br />
        [super dealloc];<br />
    }<br />
    







    'Airdrien' a écrit:


    Program received signal: “EXC_BAD_ACCESS”.


    Il s'agit d'un signal envoyé par le système d'exploitation. Il indique que le programme a tenté d'accéder à  une zone mémoire sans autorisation. La raison classique est que tu as conservé un pointeur sur un objet qui n'existe plus en mémoire.



    A priori, ce serait vaultShape.vertices.
  • AirdrienAirdrien Membre
    février 2013 modifié #15
    J'ai encore un petit soucis avec ma méthode generateVaultShape.

    La propriété vertices est un NSMutableArray que je n'arrive pas à  remplir correctement.

    Quand je veux récupérer les objets ajoutés les uns après les autres, ils sont tous égaux au dernier ajout.

    Voilà  le code :
    <br />
    -(void)generateVaultShape<br />
    {<br />
    NSLog(@&quot;generateVaultShape&quot;);<br />
    PhysicalVertex *vertex = [[PhysicalVertex alloc] init];<br />
    PhysicalPoint *point = [PhysicalPoint alloc];<br />
    [point setX:425];<br />
    [point setY:375];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    [point setX:650];<br />
    [point setY:325];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    [point setX:725];<br />
    [point setY:210];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    [point setX:510];<br />
    [point setY:375];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    [point setX:595];<br />
    [point setY:355];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    [point setX:705];<br />
    [point setY:295];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    [point setX:735];<br />
    [point setY:250];<br />
    [point setZ:0];<br />
    [vertex setAnchor:point];<br />
    NSLog(@&quot; x:%f y:%f z:%f&quot;,vertex.anchor.x,vertex.anchor.y,vertex.anchor.z);<br />
    [[self vertices] addObject:vertex];<br />
    <br />
    for (int i=0;i&lt;7;i++)<br />
      NSLog(@&quot;point%d x:%f y:%f z:%f&quot;,i,<br />
    	 [[[[self vertices] objectAtIndex:i] anchor] x],<br />
    	 [[[[self vertices] objectAtIndex:i] anchor] y],<br />
    	 [[[[self vertices] objectAtIndex:i] anchor] z]);<br />
    <br />
    }<br />
    




    et voilà  le log :





    Running...

    2013-02-02 23:25:48.582 ParApp[3848:a0f] generateVaultShape

    2013-02-02 23:25:48.585 ParApp[3848:a0f] x:425.000000 y:375.000000 z:0.000000

    2013-02-02 23:25:48.586 ParApp[3848:a0f] x:650.000000 y:325.000000 z:0.000000

    2013-02-02 23:25:48.587 ParApp[3848:a0f] x:725.000000 y:210.000000 z:0.000000

    2013-02-02 23:25:48.588 ParApp[3848:a0f] x:510.000000 y:375.000000 z:0.000000

    2013-02-02 23:25:48.589 ParApp[3848:a0f] x:595.000000 y:355.000000 z:0.000000

    2013-02-02 23:25:48.589 ParApp[3848:a0f] x:705.000000 y:295.000000 z:0.000000

    2013-02-02 23:25:48.590 ParApp[3848:a0f] x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.591 ParApp[3848:a0f] point0 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.592 ParApp[3848:a0f] point1 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.592 ParApp[3848:a0f] point2 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.593 ParApp[3848:a0f] point3 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.593 ParApp[3848:a0f] point4 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.594 ParApp[3848:a0f] point5 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.595 ParApp[3848:a0f] point6 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.595 ParApp[3848:a0f] 7

    2013-02-02 23:25:48.596 ParApp[3848:a0f] point0 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.597 ParApp[3848:a0f] point1 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.598 ParApp[3848:a0f] point2 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.599 ParApp[3848:a0f] point3 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.599 ParApp[3848:a0f] point4 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.602 ParApp[3848:a0f] point5 x:735.000000 y:250.000000 z:0.000000

    2013-02-02 23:25:48.603 ParApp[3848:a0f] point6 x:735.000000 y:250.000000 z:0.000000



    Debugger stopped.

    Program exited with status value:0.
  • AliGatorAliGator Membre, Modérateur
    C'est normal, les collections en Cocoa (NSArray, NSDictionary...) ne font pas de copie des éléments ; elles ne font qu'un "retain" sur les valeurs qu'elles contiennent, et non pas un "copy". (Ou si tu préfères, les collections maintiennent leurs objets par référence et non par copie)



    Autrement dit, quand tu fais un [vertices addObject:vertice], tu ajoutes l'objet vertice dans le tableau vertices, et ce n'est pas une copie de cet objet qui sera rajouté au tableau mais bien une référence à  l'objet lui-même (si tu as déjà  fait du C ou C++ et connais le concept de pointeur, sache qu'en Objective-C, tous les objets sont des pointeurs, d'où l'étoile dans "PhysicalVertex *" par exemple).



    Donc forcément, si tu modifies l'objet vertice même après l'avoir ajouté dans le tableau, puisque c'est unen référence qui est dans le tableau cette référence sera modifiée aussi ! Au final c'est comme si tu disais "je me fais une liste (tableau) avec toutes les voitures que je connais" et que tu mets sur cette liste "La voiture de Paul, la voiture de Jacques et la voiture de Sylvie". Si la voiture de Paul était bleue quand tu as fait cette liste, mais que Paul décide de repeindre sa voiture en rouge un jour, ça restera la voiture de Paul qui sera inscrite sur ta liste, même si elle a changé de couleur (même si ses propriétés ont changé, comme pour ton PhysicalVertex)



    ---



    Donc ce qu'il faut faire dans ton cas c'est :

    1) soit mettre une copie de ton PhysicalVertex dans ton tableau plutôt que le PhysicalVertex directement, comme ça même si tu modifies ton PhysicalVertex d'origine, la copie que tu as mise dans ton NSMutableArray ne sera cette fois-ci pas impacté par les changements de valeur de l'original

    2) soit, plus logiquement pour ton cas, créer un nouveau PhysicalVertex à  chaque fois, pour ne pas mettre à  chaque fois le même dans ton tableau, mais à  chaque fois une instance différente.
  • AliGatorAliGator Membre, Modérateur
    février 2013 modifié #17
    Au passage, pour te faciliter la tâche et réduire ton nombre de ligne de codes, je te conseille de :



    1) faire un constructeur de commodité pour tes classes, genre une méthode "+[PhysicalVertex vertexWithAnchor:]" pour tes vertices et "+[PhysicalPoint pointWithX: y: z:]" pour tes points, chacune de ces méthodes faisant un alloc, un init(*) puis affectant les propriétés adéquates de cette nouvelle instance, pour enfin retourner cet objet déjà  rempli (avec un "autorelease" avant de le retourner si jamais tu n'as pas activé ARC).

    Ca te permettrait ensuite de créer chaque PhysicalPoint en une seule ligne plutôt que d'avoir pour chaque point à  écrire 4 ou 5 lignes, genre
    [self.vertices addObject:[PhysicalVertex vertexWithAnchor: [PhysicalPoint pointWithX:595 y:355 z:0]];
    
    Tu pourrais presque même prévoir un constructeur de commodité directement pour pouvoir écrire [PhysicalVertex vertexWithAnchorAtX:595 y:355 z:0] histoire d'économiser encore du code à  taper ensuite image/wink.png' class='bbc_emoticon' alt=';)' />



    2) Surcharger la méthode "-(NSString*)description" (ou "-(NSString*)debugDescription") de tes classes, pour que quand tu appelles NSLog(@%@", ...) sur un objet de type PhysicalPoint par exemple, ça t'affiche la description de ce point directement (ses valeurs x,y et z typiquement), et du coup le NSLog que tu fais dans ta boucle ressemblera juste à  :
    NSLog(@&quot;point%d %@&quot;,i, self.vertices[i].anchor)
    




    (*) d'ailleurs tu as oublié dans ton code de faire un init sur ton PhysicalPoint, ne jamais faire un alloc sans faire de init associé ça peut t'amener des problèmes surtout en Release où les variables ne sont sinon pas mises à  zéro avant de commencer et pourraient avoir des valeurs farfelues[/i]
  • AirdrienAirdrien Membre
    février 2013 modifié #18
    J'ai un peu galéré mais ça marche :
    <br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchor:[PhysicalPoint pointWithX:735<br />
    					   Y:250<br />
    					   Z:0]]];<br />
    


    Merci beaucoup, je vais pouvoir avancer !

    image/implore.gif' class='bbc_emoticon' alt=' o:) ' />



    et ça aussi y'a pas de raison !
    <br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:425 Y:375 Z:0]];<br />
    




    ou encore :
    <br />
    NSLog(@&quot;point%d %@&quot;,i,[[self.vaultShape.vertices objectAtIndex:i] anchor]);<br />
    
  • CéroceCéroce Membre, Modérateur
    Juste un point de détail, en ObjC, on écrira plutôt:
    [PhysicalPoint pointWithX:735 y:250 z:0]
    




    Note les minuscules pour y et z.
  • AirdrienAirdrien Membre
    février 2013 modifié #20
    C'est noté.



    J'ai toujours un problème (ça va devenir une habitude !)



    Pour créer une forme de voûte de base, j'ai une méthode dans MyDocument et un push bouton.
    <br />
    -(IBAction)generateVault:(id)sender<br />
    {<br />
    [_vaultShape generateVaultShape];<br />
    int _n = [self.vaultShape.vertices count];<br />
    NSLog(@&quot;%d point(s)&quot;,_n);<br />
    for (int i=0;i&lt;_n;i++)<br />
      NSLog(@&quot;DOCUMENT vaultShape: point%d %@&quot;,i,[[self.vaultShape.vertices objectAtIndex:i] anchor]);<br />
    <br />
    _vaultShapeView.vaultShape = self.vaultShape;<br />
    _n = [_vaultShapeView.vaultShape.vertices count];<br />
    for (int i=0;i&lt;_n;i++)<br />
    {<br />
      NSLog(@&quot;DOCUMENT vaultShapeView: point%d %@&quot;,i,[[self.vaultShapeView.vaultShape.vertices objectAtIndex:i] anchor]);<br />
    }<br />
    [_vaultShapeView createPoints];<br />
    [_vaultShapeView createPath];<br />
    [_vaultShapeView standardView];<br />
    }<br />
    




    Cette action appelle une méthode de la classe VaultShape en première ligne, qui crée une forme donnée de départ :
    <br />
    -(void)generateVaultShape<br />
    {<br />
    [_vertices removeAllObjects];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:425 Y:390 Z:0]];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:660 Y:325 Z:0]];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:725 Y:210 Z:0]];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:510 Y:390 Z:0]];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:605 Y:365 Z:0]];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:715 Y:285 Z:0]];<br />
    [self.vertices addObject:[PhysicalVertex vertexWithAnchorAtX:735 Y:250 Z:0]];<br />
    int _n = [self.vertices count];<br />
    for (int i=0;i&lt;_n;i++)<br />
      NSLog(@&quot;MODELE : point%d %@&quot;,i,[[self.vertices objectAtIndex:i] anchor]);<br />
    <br />
    }<br />
    


    Tout se passe bien au premier clic, mais au deuxième : Program received signal: “EXC_BAD_ACCESS”.

    Je pense que l'erreur est dans la méthode de mon modèle, car mes NSLog ne s'affichent pas au deuxième clic.



    Très curieusement, si je double clique rapidement, le log est :

    2013-02-04 14:25:57.032 ParApp[12373:a0f] MODELE : point0 X=425.000000 Y=390.000000 Z=0.000000

    2013-02-04 14:25:57.034 ParApp[12373:a0f] MODELE : point1 <00000000 00002c40 00000000 00002840 00000000 00a06040 00000000 00004040>

    Program received signal: “EXC_BAD_ACCESS”.

    Il semble donc que la méthode de mon modèle (VaulShape) s'exécute, peut-être avant une libération non souhaitée et que je ne trouve pas!

  • CéroceCéroce Membre, Modérateur
    Teste avec Instruments > Zombies, ça pourra t'aider.



    (Instruments est une application qui fait partie des outils de dev. Je ne sais plus si on peut le lancer directement depuis Xcode 3).
  • 'Airdrien' a écrit:


    J'ai un macbook core 2 duo 2.0 GHz, late 2006, je suis resté sous Snow Leopard. Lion tourne mais ça rame.


    Lion tourne correctement sur mon MacBookPro de 2005. Je l'ai bourré de RAM raz la gueule : le double du max donné par Apple.
  • 'Céroce' a écrit:
    Teste avec Instruments > Zombies, ça pourra t'aider. (Instruments est une application qui fait partie des outils de dev. Je ne sais plus si on peut le lancer directement depuis Xcode 3).


    J'avais un zombie dans ma méthode dealloc de la classe PhysicalVertex.

    Ca fonctionne en supprimant son contenu (sauf super dealloc).

    Mais on dirait que mon code est une vraie passoire image/crybaby.gif' class='bbc_emoticon' alt=' :'( ' /> Plus d'1Mo en deux minutes... Faudrait que je me plonge plus sérieusement dans la gestion de la mémoire...


    'jpimbert' a écrit:
    Lion tourne correctement sur mon MacBookPro de 2005. Je l'ai bourré de RAM raz la gueule : le double du max donné par Apple.


    Migrer n'est pas une priorité pas plus que développer une application à  la pointe. Je suis limité à  3 Go de RAM soit diant mais j'ai quand même mis 4 image/cool.gif' class='bbc_emoticon' alt='8--)' />

    Mon appli risque de ne pas tourner sous Lion ou Mountain Lion ?
  • 'Airdrien' a écrit:


    Mais on dirait que mon code est une vraie passoire image/crybaby.gif' class='bbc_emoticon' alt=' :'( ' />/> Plus d'1Mo en deux minutes... Faudrait que je me plonge plus sérieusement dans la gestion de la mémoire...


    Un seul mot .. ARC !
  • AliGatorAliGator Membre, Modérateur
    ARC oui cela devrait lui faciliter la vie et lui éviter des oublis de release, certes.



    Mais ça serait une grave erreur que de croire qu'utiliser ARC évite d'avoir à  se plonger dans les mécanismes de gestion de la mémoire (en particulier la différence entre les weak et strong references ou les retain cycles etc) car ça, ARC ou non, ça fera quand même gonfler l'utilisation de la RAM et créera des fuites mémoire.

    Sans parler d'avoir conscience de la différence entre strong et copy ou autres concepts, toujours valables même avec ARC et toujours à  maà®triser, et qui ont un impact important sur l'empreinte mémoire d'une appli.



    ARC aide énormément en faisant beaucoup de boulot pour nous. Les ZWR aident aussi a éviter les BadAccess. Mais croire que grâce a tout ça on peut se passer de connaà®tre les principes de gestion mémoire de Cocoa c'est l'erreur à  ne pas faire !
  • Il est resté en Xcode3 sous SnowLeo. ARC n'est pas disponible pour lui.
  • CéroceCéroce Membre, Modérateur
    'Airdrien' a écrit:


    Mais on dirait que mon code est une vraie passoire image/crybaby.gif' class='bbc_emoticon' alt=' :'( ' /> Plus d'1Mo en deux minutes... Faudrait que je me plonge plus sérieusement dans la gestion de la mémoire...


    Je ne pense pas que ce soit le problème. En fait, je pense qu'il n'y a pas de problème.

    Les quelques classes que tu as créé doivent allouer quelques centaines d'octets. À mon avis, ce qui prend de la mémoire sont les nib, les bibliothèques de Cocoa, etc. Tu n'y peux rien.


    'Airdrien' a écrit:


    Migrer n'est pas une priorité pas plus que développer une application à  la pointe. Je suis limité à  3 Go de RAM soit diant mais j'ai quand même mis 4 image/cool.gif' class='bbc_emoticon' alt='8--)' />


    Disons que Xcode 4 offre beaucoup de confort. Il m'est arrivé de retourner sous Xcode 3 pour compiler pour Mac OS 10.5, et le choc fut rude!


    'Airdrien' a écrit:


    Mon appli risque de ne pas tourner sous Lion ou Mountain Lion ?


    Il y a une compatibilité ascendante, mais il faudra quand même tester. Il arrive qu'on emploie mal les API, et ça peut fonctionner sous 10.6, mais plus sous 10.7.
  • Pour l'instant je reste sous xcode 3, donc pas d'option Arc. Je suis d'accord avec toi AliGator, mieux vaut prendre de bonnes habitudes et apprendre a bien gerer la memoire.

    Ceroce tu me rassures !

    Merci a vous tous pour vos bons conseils, des que j'ai une version un tant soit peu fonctionnelle, je vous la soumets pour test Lion ;-)

    Il est temps pour moi d'etoffer mon modele avec :

    - une forme a plat,

    - des profils,

    - le suspentage.

    Je vais avoir a discretiser VaultShape et FlatShape pour accueillir mes profils, equipes de points d'ancrages pour les suspentes.

    Une idee pour transformer une forme de bezier constituee de 3 ou 4 vertices en une forme plus fournies?

    Je pense aplatir la forme et cheminer dans une boucle pour ajouter des points.

    L'utilisateur devra pouvoir choisir un nombre de profils et une loi de repartition, non lineaire car c'est trop simpliste et pas coherent avec l'etat de l'art.

    Je vous en reparle dans un moment...

    Encore merci !
  • Pour info XCode 4.2 tourne sur mon vieux Mac Mini, avec seulement 1 Go de RAM et Snow Leopard !
  • 'Draken' a écrit:


    Pour info XCode 4.2 tourne sur mon vieux Mac Mini, avec seulement 1 Go de RAM et Snow Leopard !


    Si je me souviens bien elle était pas très stable cette version.
  • J'ai des plantages de temps en temps, effectivement ! Enfin normalement j'aurais un nouveau Mac dans 5 semaines. À moi Xcode 4.6 bientôt ! * espoir dans la voix *
Connectez-vous ou Inscrivez-vous pour répondre.