
PTC Windchill
PTC WindchillConnect operations across the company with Dynamics 365 Business Central
Manufacturing companies now require real-time information sharing, dynamic data visualization, and seamless collaboration across departments. These needs are more critical than ever before.
A PLM (Product Lifecycle Management) solution offers easy and secure data access for teams across departments and locations. It ensures quality-focused processes and a data-driven approach to manufacturing.
PTC's PLM solution, Windchill, provides a complete package to manage your product lifecycle. It offers end-to-end solutions for all your product-related data and processes.
Windchill's open architecture ensures seamless integration with your existing IT systems, including ERP, Field Service, CAD, and IoT. It offers comprehensive out-of-the-box functionality and configurable role- and task-based applications.
Benefits of Windchill
How can one software solution streamline communication between different points in the value chain? In short: centralization. Your PLM solution becomes your reference tool through which data can be consistently managed and accessed by all stakeholders.

User friendly
Effortlessly manage your finances from start to finish. Discover how you can stay on top of your budget, speed up monthly and yearly closings, and automate bank reconciliations. Experience the power of unlimited dimensions for precise tracking of your fixed assets.

Integration with other solutions
Manage data at scale with integration of multiple systems thanks to PTC Windchill's open architecture. It allows you to connect your ERP or other IT systems with Windchill.

Secure PLM platform
Protect your company's data and product information, regardless of whether you work with internal or external employees.

One repository for all product design data
PTC Windchill houses a variety of product-related data, from multi-dimensional data, to BoM's for engineering, production and service, version control and workflows.

Foster innovation
PLM solutions help eliminate silo structures by removing the traditional limitations that arise from working in different systems. Thereby you get a digital ecosystem that promotes innovation.

Change management
Change management is standard within PTC Windchill.

Accessible
With built-in rights management, only specific profiles can access the information entrusted to them. Furthermore, you can connect from any device via a web browser.

Reduce costs
PTC Windchill gives you a better view of the different parts and quantities needed to make a product, so you can react faster based on purchasing and inventory.
Integration with other business systems
By using open standards within Windchill, you can easily integrate the solution with other business systems, including CAD, ERP, and IoT. This way, you get a solid foundation for a product-driven digital common thread and a continuous feedback loop.

These challenges are addressed with PTC Windchill
On-time delivery
Delivering on time to customers is not always easy. With PTC Windchill, you can manage project status, streamline processes, and improve collaboration between the design and production departments.
High costs:
Finding ways to reduce costs remains a top priority for every manufacturing company. PTC Windchill provides better insight into the various components and quantities needed to produce a product, allowing you to better manage purchasing and inventory.
Regulatory compliance:
In specific manufacturing subsectors, PTC Windchill allows you to accurately document regulations and ensures compliance with safety and quality standards.
Supply chain disruption:
Having issues with the delivery of components or raw materials? With PTC Windchill, you can monitor relationships with your suppliers.
Internal collaboration:
Miscommunication and manual errors when transferring designs from the design department to production are a thing of the past with PTC Windchill. The solution automates and visualizes these processes, enhancing collaboration.
Highlighted capabilities of PTC Windchill
PTC Windchill manages all product-related information. Collaborate seamlessly on product designs with different teams and across various locations by integrating multiple CAD systems into one secure platform. This accelerates design cycles, reduces errors, and fosters innovation.
Maintain consistency throughout the entire product lifecycle by digitally connecting engineering, supply chain, manufacturing, sales, and service teams. This enhances efficiency and decision-making while reducing costs.
Ensure precision and accountability during the modification process by setting up automated workflows with built-in governance and traceability. This helps minimize errors, streamline processes, and ensure product integrity.
Ensure a uniform approach with real-time insight into product data for production planning, validate advanced manufacturing processes, digitize the shop floor, conduct quality control, optimize strategic purchasing, and support mobile service technicians.
Ensure a smooth flow of information between engineering and production by establishing integrated processes for manufacturing, regardless of location. This increases efficiency, improves product quality, and reduces lead times.
Quality, reliability, and safety are integrated throughout the entire lifecycle by applying quality control processes in design, production, and service. This enhances customer satisfaction, reduces defects, and minimizes risks.
Simplify product complexity and reduce costs by implementing a classification strategy to prevent duplicate parts, promote reuse, save costs, improve inventory management, and enhance product reliability.
Effectively manage different product variants and configurations by utilizing lifecycle management tools. This increases flexibility, enhances customization, and streamlines processes to meet customer needs.
Collaborate with suppliers while protecting intellectual property by securely sharing data and tracking deliverables in the global supply chain to improve supplier relationships, optimize supply chain efficiency, and mitigate risks.

Error executing template "Designs/Swift/Paragraph/9a_Content_gates_module.cshtml" System.ArgumentException: field "$facets" was not indexed with SortedSetDocValues at Lucene.Net.Facet.SortedSet.DefaultSortedSetDocValuesReaderState..ctor(IndexReader reader, String field) at Dynamicweb.Indexing.Lucene.LuceneIndexProvider.<get_ReaderState>b__14_0(String path) at Dynamicweb.Indexing.Lucene.LuceneIndexProvider.SearchInternal(IQuery query, QuerySettings settings) at Dynamicweb.Indexing.Queries.IndexQueryProvider.Query(IQuery query, QuerySettings settings) at Dynamicweb.Indexing.Querying.QueryService.Query(IQuery query, QuerySettings settings) at NineAltitudes.CustomCode.NineAContent.ContentClient.NineAContentService.GetResults(Int32 pageSize, IQueryService queryService, IQuery query, Dictionary`2 parameters) at NineAltitudes.CustomCode.NineAContent.ContentClient.NineAContentService.GetContentByTagFilters(Int32 pageAreaId, IEnumerable`1 contentTypes, IEnumerable`1 tagFilters, Int32 pageSize) at CompiledRazorTemplates.Dynamic.RazorEngine_866ad1bd4baa483db592c78e5f8df5c5.GetFacetedContent(ParagraphViewModel model, Int32 maxItems, Int32 pageAreaId, String tagFilter) at CompiledRazorTemplates.Dynamic.RazorEngine_866ad1bd4baa483db592c78e5f8df5c5.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using NineAltitudes.CustomCode.NineAContent; 3 @using Dynamicweb.Rendering; 4 @using Dynamicweb.Extensibility; 5 @using Dynamicweb.Frontend; 6 @using System.Linq; 7 @using NineAltitudes.CustomCode.NineAContent.ContentClient; 8 9 @{ 10 const int maxItems = 7; 11 12 string title = Model.Item.GetString("Title"); 13 14 var filter = Dynamicweb.Context.Current.Request.QueryString.Get("filter"); 15 16 var pageView = Dynamicweb.Frontend.PageView.Current(); 17 int currentPageAreaId = pageView.AreaID; 18 19 (var content, var dimensions) = GetFacetedContent(Model, maxItems, currentPageAreaId, filter); 20 21 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 22 var decorations = Model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 23 24 string contentPadding = Model.Item.GetRawValueString("ContentPadding", "none"); 25 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 26 contentPadding = contentPadding == "small" ? "p-3 p-md-3" : contentPadding; 27 contentPadding = contentPadding == "large" ? "p-5 p-md-5" : contentPadding; 28 29 string buttonSize = Model.Item.GetString("ButtonSize") != "regular" ? Model.Item.GetString("ButtonSize") : String.Empty; 30 31 string buttonShape = "rounded-2"; 32 33 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 34 35 string cardTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("CardTheme")) ? " theme " + Model.Item.GetRawValueString("CardTheme").Replace(" ", "").Trim().ToLower() : ""; 36 string cardButtonText = Model.Item.GetString("CardButtonText"); 37 string cardButtonStyle = Model.Item.GetString("CardButtonStyle") == "btn-link" ? "btn-link ps-0" : Model.Item.GetString("CardButtonStyle"); 38 string cardButtonSize = Model.Item.GetString("CardButtonSize") != "regular" ? Model.Item.GetString("CardButtonSize") : String.Empty; 39 bool showCardButtonIcon = Model.Item.GetString("CardButtonType") == "icon" || Model.Item.GetString("CardButtonType") == "both"; 40 bool showCardButtonText = Model.Item.GetString("CardButtonType") == "text" || Model.Item.GetString("CardButtonType") == "both"; 41 string cardTitleSize = Model.Item.GetString("CardTitleSize"); 42 string cardShape = Model.Item.GetString("CardShape"); 43 string cardShapeCSS = cardShape == "boxed" ? "rounded-0" : "rounded-4"; 44 45 string ratio = Model.Item.GetString("ImageAspectRatio"); 46 ratio = ratio != "0" ? ratio : string.Empty; 47 string ratioCssClass = ratio != string.Empty ? " ratio" : string.Empty; 48 string ratioVariable = ratio != string.Empty ? "style=\"--bs-aspect-ratio: " + ratio + "\"" : string.Empty; 49 50 string secondChildOfGridCSS = content.Count == 5 || content.Count == 7 ? "grid g-col-12 g-col-lg-8" : "grid g-col-12"; 51 string secondChildOfGridChildCSS = content.Count == 5 ? "g-col-12 g-col-md-6" : content.Count == 7 ? "g-col-12 g-col-md-6 g-col-lg-4" : "g-col-12 g-col-md-6 g-col-lg-3"; 52 53 bool gridShouldBeSplit = (content.Count == 7 || content.Count == 5); 54 } 55 56 @functions { 57 58 private (List<Dynamicweb.Frontend.ItemViewModel> content, List<Dynamicweb.Frontend.ItemViewModel> dimensions) GetFacetedContent(ParagraphViewModel model, int maxItems, int pageAreaId, string? tagFilter = null) 59 { 60 var selectedTags = GetSelectedTags(model); 61 62 var contentTypes = model.Item?.GetList("ContentTypes")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); 63 64 var service = ServiceLocator.Current.GetInstance<INineAContentQueryService>(); 65 var contentWithTags = service.GetContentByTagFilters(pageAreaId, contentTypes, selectedTags, maxItems); 66 67 var availableFilterDimensionPageIds = GetAvailableFilterDimensionPageIds(service, contentWithTags, pageAreaId); 68 var dimensions = GetPagesByPageId(availableFilterDimensionPageIds); 69 70 if (tagFilter != null) 71 { 72 contentWithTags = 73 contentWithTags 74 .Where(x => x.Tags.Any(y => y == tagFilter)) 75 .ToArray(); 76 } 77 78 var localizedTagPageIds = contentWithTags.Select(tag => tag.PageId).Take(maxItems); 79 var content = GetPagesByPageId(localizedTagPageIds); 80 81 return (content, dimensions); 82 } 83 84 private string[] GetSelectedTags(ParagraphViewModel model) 85 { 86 var industry_filters = model.Item?.GetList("Filters_Tags_Industries")?.GetRawValue().OfType<string>(); 87 var vendor_filters = model.Item?.GetList("Filters_Tags_Vendors")?.GetRawValue().OfType<string>(); 88 var domain_filters = model.Item?.GetList("Filters_Tags_Domains")?.GetRawValue().OfType<string>(); 89 var solution_filters = model.Item?.GetList("Filters_Tags_Solutions")?.GetRawValue().OfType<string>(); 90 var product_filters = model.Item?.GetList("Filters_Tags_Products")?.GetRawValue().OfType<string>(); 91 var country_filters = model.Item?.GetList("Filters_Tags_Countries")?.GetRawValue().OfType<string>(); 92 var service_filters = model.Item?.GetList("Filters_Tags_Services")?.GetRawValue().OfType<string>(); 93 var topic_filters = model.Item?.GetList("Filters_Tags_Topics")?.GetRawValue().OfType<string>(); 94 95 var allTags = (industry_filters ?? []) 96 .Concat(vendor_filters ?? []) 97 .Concat(domain_filters ?? []) 98 .Concat(solution_filters ?? []) 99 .Concat(product_filters ?? []) 100 .Concat(country_filters ?? []) 101 .Concat(service_filters ?? []) 102 .Concat(topic_filters ?? []) 103 .ToArray(); 104 105 return allTags; 106 } 107 108 private IEnumerable<int> GetAvailableFilterDimensionPageIds(INineAContentQueryService service, INineATaggedContent[] contentWithTags, int pageAreaId) 109 { 110 var interactiveFilter = Model.Item?.GetString("Filter_Interactive_Tag_Dimension"); 111 112 if (string.IsNullOrWhiteSpace(interactiveFilter)) 113 return []; 114 115 var interactiveFilterDimension = NineATag.FromPrefix(interactiveFilter); 116 if (interactiveFilterDimension == null) 117 return []; 118 119 var dimensionsTagIds = contentWithTags.GetUsedTagsWith(interactiveFilterDimension); 120 if (!dimensionsTagIds.Any()) 121 return []; 122 123 var tagContent = service.GetContentByTagIds(pageAreaId, dimensionsTagIds, contentWithTags.Length); 124 var localizedTagPageIds = tagContent.Select(tag => tag.PageId); 125 126 return localizedTagPageIds; 127 } 128 129 private List<Dynamicweb.Frontend.ItemViewModel> GetPagesByPageId(IEnumerable<int> pageIds) 130 { 131 var lists = new List<Dynamicweb.Frontend.ItemViewModel>(); 132 133 if (pageIds.Any()) 134 { 135 foreach (var tagPageID in pageIds) 136 { 137 var page = Dynamicweb.Content.Services.Pages?.GetPage(Dynamicweb.Core.Converter.ToInt32(tagPageID)) ?? null; 138 var viewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(page)?.Item ?? null; 139 140 if (viewModel != null) 141 { 142 lists.Add(viewModel); 143 } 144 } 145 } 146 return lists; 147 148 } 149 } 150 151 <div class="item_@Model.Item.SystemName.ToLower() @theme @contentPadding"> 152 @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) 153 { 154 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h2"); 155 string headingLevel = Model.Item.GetString("HeadingLevel", "h2"); 156 string headingLevelStart = $"<{headingLevel} class=\"{titleFontSize} mb-4\" id=\"gates_{@Model.PageID}\">"; 157 string headingLevelStop = $"</{headingLevel}>"; 158 159 @headingLevelStart 160 @Model.Item.GetString("Title") 161 @headingLevelStop 162 } 163 164 <div class="d-flex gap-1 gap-sm-3 my-3 flex-wrap "> 165 @if (dimensions != null) 166 { 167 var relativeUri = Dynamicweb.Context.Current.Request.RawUrl; 168 var host = Dynamicweb.Context.Current.Request.Url.Host; 169 if (host.Contains("localhost")) 170 { 171 host = host + ":" + Dynamicweb.Context.Current.Request.Url.Port; 172 } 173 174 var newUri = new Uri(Dynamicweb.Context.Current.Request.Url, relativeUri); 175 176 @foreach (var category in dimensions) 177 { 178 var tagId = category.GetString("tag_id"); 179 var curRef = $"{newUri.Scheme}://{host}{newUri.AbsolutePath}"; 180 var link = $"{curRef}?filter={tagId}#gates_{Model.PageID}"; 181 182 183 string isActive = filter == tagId ? "active " : ""; 184 string isActiveBtnType=filter == tagId ? "btn-secondary":"btn-primary"; 185 <div> 186 <a class="btn @isActiveBtnType @buttonSize @buttonShape @isActive text-nowrap" href="@link"> @category.GetString("Title")</a> 187 </div> 188 } 189 190 @if (!string.IsNullOrEmpty(filter)) 191 { 192 var curRef = $"{newUri.Scheme}://{host}{newUri.AbsolutePath}"; 193 var link = $"{curRef}#gates_{Model.PageID}"; 194 195 <div> 196 <a class="btn btn-link @buttonSize @buttonShape" href="@link" style="padding-block: var(--swift-button-primary-padding-y);"> @Translate("Clear Filter")</a> 197 </div> 198 } 199 200 } 201 @if (Model.Item.GetBoolean("Show_GoTo_Button")) 202 { 203 var gotoButtonText = Model.Item.GetString("GoTo_Button_Text"); 204 var link = Model.Item.GetString("GoTo_Link"); 205 206 @if (!string.IsNullOrEmpty(gotoButtonText) && !string.IsNullOrEmpty(link)) 207 { 208 <a href="@link" class="btn btn-link ms-auto @buttonSize @buttonShape" style="padding-block: var(--swift-button-primary-padding-y);">@gotoButtonText</a> 209 } 210 } 211 212 </div> 213 214 215 <div class="grid g-col-12" style="background-color:transparent"> 216 @{ 217 int itemCount = 0; 218 } 219 @foreach (ItemViewModel item in content) 220 { 221 itemCount++; 222 223 //if the there are 5 or 7 items, the first item should fill up more space 224 @if (itemCount==1 && gridShouldBeSplit) 225 { 226 @:<div class="g-col-12 g-col-lg-4"> 227 } 228 229 // If there are 5 or 7 items, the rest of the items should be in a seperate grid. 230 @if ((itemCount==2 && gridShouldBeSplit)) 231 { 232 @:<div class="@secondChildOfGridCSS"> 233 } 234 235 // All items that are not the first one, in case case there are 5 or 7 items, should have their own classes. 236 //Or if there aren't 5 or 7 items, then all should have this css 237 @if ((itemCount!=1 && gridShouldBeSplit) || !gridShouldBeSplit) 238 { 239 240 @:<div class="@secondChildOfGridChildCSS"> 241 242 } 243 244 <article class="card h-100 border-0 @cardTheme @cardShapeCSS overflow-hidden shadow-hover" itemscope="" itemtype="https://schema.org/CreativeWork" style="background-color: var(--swift-background-color)"> 245 246 @if (!String.IsNullOrEmpty(item.GetString("Image"))) 247 { 248 <a class="position-relative" title="@item.GetString("Title")" href="@item.Link" tabindex="-1"> 249 <figure class="overflow-hidden m-0 mx-auto @ratioCssClass" @ratioVariable> 250 @{ 251 var coverImagePath = Dynamicweb.Context.Current.Server.UrlEncode(item.GetString("Image")); 252 string image = item.GetString("Image"); 253 254 string coverImagePathM = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=640&format=webp"; 255 string coverImagePathL = $"/Admin/Public/GetImage.ashx?image={coverImagePath}&width=960&format=webp"; 256 string imagePathFallBack = coverImagePathM; 257 258 <img srcset=" 259 @coverImagePathM 640w, 260 @coverImagePathL 960w" 261 src="@imagePathFallBack" 262 sizes="(min-width: 992px) 25vw, 100vw" 263 loading="lazy" 264 decoding="async" 265 class="img-fluid image-zoom-lg-1-hover" 266 style="object-fit:cover; object-position: 50% 50%;" 267 alt="@item.GetString("Title")"> 268 } 269 </figure> 270 </a> 271 } 272 273 <div class="col d-flex flex-column p-3"> 274 <div class="card-body p-0 d-flex flex-column gap-2"> 275 <a class="text-decoration-none text-decoration-underline-hover" href="@item.Link"> 276 <h3 class="@cardTitleSize mb-0" itemprop="headline"> @item.GetString("Title")</h3> 277 </a> 278 279 @if (!String.IsNullOrEmpty(item.GetRawValueString("Summary"))) 280 { 281 <p class="m-0 opacity-75">@item.GetRawValueString("Summary")</p> 282 } 283 284 @if (!String.IsNullOrWhiteSpace(cardButtonText)) 285 { 286 <div class="mt-auto"> 287 <a href="@item.Link" class="btn @cardButtonStyle @cardButtonSize lh-1 text-start"> 288 289 @if (showCardButtonIcon) 290 { 291 <span class="icon-auto"> 292 @ReadFile(iconPath + "arrow-right.svg") 293 </span> 294 } 295 296 @if (showCardButtonText) 297 { 298 <span>@cardButtonText</span> 299 } 300 </a> 301 </div> 302 } 303 </div> 304 305 <div class="card-footer p-0 pt-3 border-top-0"> 306 <div class="d-flex align-items-center justify-content-between gap-3"> 307 308 @if (!String.IsNullOrEmpty(item.GetString("PublishedDate")) && item.GetDateTime("PublishedDate").Year != 1900 && item.GetDateTime("PublishedDate") != DateTime.MinValue) 309 { 310 string articleDateTime = item.GetDateTime("PublishedDate").Year + "-" + 311 item.GetDateTime("PublishedDate").Month + "-" + item.GetDateTime("PublishedDate").Day; 312 string publishedDate = item.GetDateTime("PublishedDate").ToShortDateString(); 313 314 <div class="d-flex align-items-center gap-1 fs-8 opacity-75"> 315 <div class="icon-1"> 316 @ReadFile(iconPath + "calendar.svg") 317 </div> 318 <time datetime="@articleDateTime" itemprop="datePublished">@publishedDate</time> 319 </div> 320 } 321 </div> 322 </div> 323 </div> 324 </article> 325 326 @if ((itemCount!=1 && gridShouldBeSplit) || !gridShouldBeSplit) 327 { 328 @:</div> 329 } 330 @if ((itemCount==content.Count && gridShouldBeSplit)) 331 { 332 @:</div> 333 } 334 @if (itemCount==1 && gridShouldBeSplit) 335 { 336 @:</div> 337 } 338 } 339 </div> 340 </div> 341
Frequently asked questions about Windchill:
In addition to PTC Creo Parametric, Windchill is also compatible with other CAD tools. The integration makes collaboration between development and production easier and ensures fewer manual errors when preparing and converting BoM's, as PTC Windchill automates this.
Integration with the ERP system makes it possible to monitor stocks and production at project level. 9A Windchill - Dynamics 365 Supply Chain Management Connector from 9altitudes is a real-time, two-way integration that reduces time-to-market for custom and configurable products.
By connecting PTC Windchill to an IoT solution like PTC ThingWorx, you can monitor and improve your connected end products and machines on the production floor. Through IoT, you gain insight into the performance and use of your products and machines. You can then use this information to optimize them.

9altitudes as your PLM-partner
9altitudes is an international digital partner that automates, optimizes and continuously improves business processes end-to-end. We help manufacturing companies like yours reach new heights using Microsoft, PTC and Tulip software in combination with our own industry-specific solutions.
We have the expertice to ensure that your organization doesn't just get a new software, but gets a strategic tool that supports your company across multiple departments and enable you go create a better digital tomorrow.
Get in touch
Whether you're looking for an assessment to see if Windchill is the right fit, need help with implementation, or are seeking a new partner for your existing solution, we're here to help. Reach out to us today to learn more about how we can guide through the next part of your digital transformation.
