Артем, по видимому решить эту задачу на уровне адаптивного фрагмента будет не просто (если вообще такое возможно). В качестве временного решения, можно использовать макрос для создания/обновления существующих записей в структуре изделия. Но чтобы макрос корректно работал, тела должны иметь однородную структуру зависимостей. Я немного поэкспериментировал и вот что у меня получилось.
[CODE]
using System.Linq;
using System.Windows.Forms;
using TFlex.Model;
using TFlex.Model.Data.ProductStructure;
using TFlex.Model.Model3D;
using TFlex.Model.Model3D.Geometry;
namespace Test
{
public class ProductStructureHelper
{
public static void Run()
{
var document = TFlex.Application.ActiveDocument;
if (document == null)
return;
var objects = document.Selection.GetAllObjects();
if (objects.Length == 0)
{
MessageBox.Show("Перед запуском макроса, необходимо выбрать объект!", "T-FLEX CAD");
return;
}
foreach (var obj in objects)
{
if (obj.GroupType != ObjectType.Extrusion)
continue;
var extrusion = obj as ThickenExtrusion;
if (extrusion == null)
continue;
UpdateProductStructure(document, extrusion);
}
}
private static void UpdateProductStructure(Document document, ThickenExtrusion extrusion)
{
foreach (var ps in document.GetProductStructures())
{
var scheme = ps.GetScheme();
if (scheme.Name != "Спецификация")
continue;
var pHelper = new ProcHelper(ps, scheme);
bool updated = false;
document.BeginChanges("");
foreach (var row in ps.GetAllRowElements())
{
if (pHelper.GetName(row).Contains("Сегмент") &&
row.ParentRowElement.LinkedObjects.Contains(extrusion))
{
TaskProcessing(extrusion, pHelper, row, 0);
updated = true;
}
}
if (updated)
{
ps.UpdateStructure();
document.EndChanges();
return;
}
var parentRow = ps.AddElement();
pHelper.SetName(parentRow, extrusion.Name);
parentRow.LinkedObjects.Add(extrusion);
TaskProcessing(extrusion, pHelper, parentRow, 1);
ps.UpdateStructure();
document.EndChanges();
}
}
private static void TaskProcessing(ThickenExtrusion extrusion, ProcHelper pHelper, RowElement row, int flag)
{
for (int i = 0; i < extrusion.Profile.Length; i++)
{
var topolRef = (extrusion.Profile[i] as ModelContour).Reference as TopolReference;
if (topolRef == null)
continue;
var face = topolRef.Topol as ModelFace;
if (face == null)
continue;
RowElement _row;
foreach (ModelEdge edge in face.Edges)
{
var id = edge.Identify;
if (flag > 0)
{
_row = pHelper.ProductStructure.AddElement();
_row.ParentRowElement = row;
}
else
{
_row = row;
if (!pHelper.GetName(_row).Contains(id))
continue;
}
var length = edge.Curve.Length(edge.Interval) * 1000;
var value = string.Format("Сегмент [id: {0}, len: {1}]",
id, length);
pHelper.SetName(_row, value);
}
}
}
}
public class ProcHelper
{
readonly Scheme scheme;
public ProcHelper(ProductStructure ps, Scheme scheme)
{
this.scheme = scheme;
ProductStructure = ps;
}
public ProductStructure ProductStructure { get; }
public string GetName(RowElement row)
{
foreach (var p in scheme.Parameters)
{
if (p.SynonymName == "Description")
{
return row[p].Text;
}
}
return null;
}
public void SetName(RowElement row, string value)
{
foreach (var p in scheme.Parameters)
{
if (p.SynonymName == "Description")
{
row[p].Text = value;
break;
}
}
}
}
}
[/CODE]
Целевые объекты обработки -- это тела, созданные при помощи операции "Выталкивание", с привязкой к граням на базовой форме. По сути, макрос создает записи в структуре изделия с привязкой к операции "Выталкивание" для определения родительского элемента. Дочерние элементы не имеют привязку к ребрам, но они идентифицируются по свойству [B]Identify[/B] при повторной обработке записей.
[CODE]
using System.Linq;
using System.Windows.Forms;
using TFlex.Model;
using TFlex.Model.Data.ProductStructure;
using TFlex.Model.Model3D;
using TFlex.Model.Model3D.Geometry;
namespace Test
{
public class ProductStructureHelper
{
public static void Run()
{
var document = TFlex.Application.ActiveDocument;
if (document == null)
return;
var objects = document.Selection.GetAllObjects();
if (objects.Length == 0)
{
MessageBox.Show("Перед запуском макроса, необходимо выбрать объект!", "T-FLEX CAD");
return;
}
foreach (var obj in objects)
{
if (obj.GroupType != ObjectType.Extrusion)
continue;
var extrusion = obj as ThickenExtrusion;
if (extrusion == null)
continue;
UpdateProductStructure(document, extrusion);
}
}
private static void UpdateProductStructure(Document document, ThickenExtrusion extrusion)
{
foreach (var ps in document.GetProductStructures())
{
var scheme = ps.GetScheme();
if (scheme.Name != "Спецификация")
continue;
var pHelper = new ProcHelper(ps, scheme);
bool updated = false;
document.BeginChanges("");
foreach (var row in ps.GetAllRowElements())
{
if (pHelper.GetName(row).Contains("Сегмент") &&
row.ParentRowElement.LinkedObjects.Contains(extrusion))
{
TaskProcessing(extrusion, pHelper, row, 0);
updated = true;
}
}
if (updated)
{
ps.UpdateStructure();
document.EndChanges();
return;
}
var parentRow = ps.AddElement();
pHelper.SetName(parentRow, extrusion.Name);
parentRow.LinkedObjects.Add(extrusion);
TaskProcessing(extrusion, pHelper, parentRow, 1);
ps.UpdateStructure();
document.EndChanges();
}
}
private static void TaskProcessing(ThickenExtrusion extrusion, ProcHelper pHelper, RowElement row, int flag)
{
for (int i = 0; i < extrusion.Profile.Length; i++)
{
var topolRef = (extrusion.Profile[i] as ModelContour).Reference as TopolReference;
if (topolRef == null)
continue;
var face = topolRef.Topol as ModelFace;
if (face == null)
continue;
RowElement _row;
foreach (ModelEdge edge in face.Edges)
{
var id = edge.Identify;
if (flag > 0)
{
_row = pHelper.ProductStructure.AddElement();
_row.ParentRowElement = row;
}
else
{
_row = row;
if (!pHelper.GetName(_row).Contains(id))
continue;
}
var length = edge.Curve.Length(edge.Interval) * 1000;
var value = string.Format("Сегмент [id: {0}, len: {1}]",
id, length);
pHelper.SetName(_row, value);
}
}
}
}
public class ProcHelper
{
readonly Scheme scheme;
public ProcHelper(ProductStructure ps, Scheme scheme)
{
this.scheme = scheme;
ProductStructure = ps;
}
public ProductStructure ProductStructure { get; }
public string GetName(RowElement row)
{
foreach (var p in scheme.Parameters)
{
if (p.SynonymName == "Description")
{
return row[p].Text;
}
}
return null;
}
public void SetName(RowElement row, string value)
{
foreach (var p in scheme.Parameters)
{
if (p.SynonymName == "Description")
{
row[p].Text = value;
break;
}
}
}
}
}
[/CODE]
Целевые объекты обработки -- это тела, созданные при помощи операции "Выталкивание", с привязкой к граням на базовой форме. По сути, макрос создает записи в структуре изделия с привязкой к операции "Выталкивание" для определения родительского элемента. Дочерние элементы не имеют привязку к ребрам, но они идентифицируются по свойству [B]Identify[/B] при повторной обработке записей.