2017-11-14 1 views
2

Ich entwickelte eine App, die die Möglichkeit bietet, die Unterteilungsergebnisse eines 3D-Modells im Vorüberblick anzuzeigen. Ich habe meine eigenen catmull clark-Unterteilungsfunktionen, um die Geometrie dauerhaft zu ändern, aber ich verwende die .subdivisionLevel -Eigenschaft von SCNGeometry, um das Modell vorübergehend als Vorschau zu unterteilen. In den meisten Fällen bedeutet die Vorschau nicht automatisch, dass der Benutzer sich für die permanente Option entscheidet.Reparieren oder Vermeiden von Speicherverlust in der Standard-Third-Party-Bibliothek

.subdivisionLevel verwendet (genau wie MDLMeshs Unterteilung, die ich als Workaround ausprobierte) Pixars OpenSubdiv zur eigentlichen Unterteilung und Glättung. Es funktioniert schneller als meine eigenen, aber wichtiger noch, es ändert nicht permanent die Vertex-Daten, die ich über eine SCNGeometry-Quelle zur Verfügung stelle.

Das Problem ist, ich kann es nicht erreichen Speicher zu verlieren. Ich habe das vor langer Zeit zum ersten Mal bemerkt, dachte, dass es etwas in meinem Code ist. Ich denke nicht, dass es nur eine bestimmte IOS-Version ist und es passiert sowohl in Swift als auch in Objective C. Schließlich habe ich ein kleines Beispiel mit nur einer Zeile zur SceneKit-Spielvorlage in Xcode eingerichtet und die Unterteilung des Schiffs auf 1 gesetzt sofort führt zu Speicherleck:

enter image description here

ich einen Fehlerbericht an Apple vor einer Woche eingereicht, aber ich bin nicht sicher, ob ich bald eine Antwort oder ein Update zu jeder Zeit erwarten kann, oder überhaupt nicht. Der Screenshot stammt aus einem Test mit einem sehr kleinen Modell, aber selbst bei kleinen Modellen (Hunderte bis ein paar tausend Vertices) leckt es viel und schnell und führt zum Absturz der App.

zu reproduzieren, ein neues Projekt in Xcode auf der Grundlage der SceneKit Spiel-Vorlage erstellen und die folgenden Zeilen in den handletap:

if result.node.geometry!.subdivisionLevel == 3 { 
    result.node.geometry!.subdivisionLevel = 0 
    } else { 
    result.node.geometry!.subdivisionLevel = 3 
    } 

(! Entfernen Sie die für Ziel c) das Schiff Tippen Megabyte zu lecken, tippen Sie es etwas mehr und es summiert sich schnell.

OpenSubdiv wird in 3D Studio Max sowie anderen offensichtlich verwendet und es scheint in Apples Implementierung zu sein. Meine Frage ist also: Gibt es eine Möglichkeit, dieses Problem zu beheben/zu vermeiden, ohne die Unterteilungsfunktionen von SceneKit vollständig aufzugeben, oder ist eine Antwort von Apple meine einzige Chance?

+0

Warten Sie nicht auf Apple, nahmen Sie 3 iOS-Versionen, um einen einfachen Fehler zu beheben, der jede bidirektionale App betrifft, die die horizontale Bildlaufansicht verwendet !! – Yitzchak

Antwort

0

Durch die WWDC-Videos, um eine Vorstellung davon zu bekommen, wie engagiert Apple OpenSubdiv ist und damit die Möglichkeit, die Lecks zu beheben, fand ich die Unterteilung auf der GPU durch Metal seit dem letzten SceneKit-Update.

Hier sind die erforderlich zwei Leitungen (Swift), wenn Sie Unterteilung in SceneKit oder Modell IO verwenden möchten:

let tess = SCNGeometryTessellator() 
geometry.tessellator = tess 

(von WWDC 2017 Was in Scenekit, 23.45 in das Video neu)

Dadurch wird die Unterteilung auf der GPU durchgeführt (daher schneller, besonders bei höheren Pegeln), weniger Speicher belegt und, was am wichtigsten ist, wird der Speicher freigegeben, wenn die Unterteilung niedriger oder wieder auf Null gesetzt wird.

+0

Dieses Problem (Speicherverluste) ist in IOS 11.3 Beta behoben. Die Verwendung des Tessellators verhindert Speicherlecks, glättet jedoch die Normalen nicht richtig. Die beste Option im Moment, wenn Sie keine adaptive Unterteilung wünschen, ist die Verwendung eines Tessellators. Dies wird Unterteilung auf der CPU verwenden, aber wird nicht undicht werden und wird wie gewöhnlich beabsichtigt aussehen. – Xartec

Verwandte Themen